@@ -18,7 +18,9 @@ use vault_registry::{
1818// Pallets
1919use crate :: Pallet as Redeem ;
2020use btc_relay:: Pallet as BtcRelay ;
21+ use issue:: Pallet as Issue ;
2122use oracle:: Pallet as Oracle ;
23+ use primitives:: issue:: IssueRequest ;
2224use security:: Pallet as Security ;
2325use vault_registry:: Pallet as VaultRegistry ;
2426
@@ -123,6 +125,154 @@ fn mint_vault_collateral<T: crate::Config + loans::Config>(vault_id: &DefaultVau
123125 }
124126}
125127
128+ fn get_vault_id < T : crate :: Config > ( name : & ' static str ) -> DefaultVaultId < T > {
129+ VaultId :: new (
130+ account ( name, 0 , 0 ) ,
131+ get_collateral_currency_id :: < T > ( ) ,
132+ get_wrapped_currency_id :: < T > ( ) ,
133+ )
134+ }
135+
136+ fn register_vault < T : crate :: Config > ( vault_id : & DefaultVaultId < T > , issued_tokens : Amount < T > ) {
137+ let origin = RawOrigin :: Signed ( vault_id. account_id . clone ( ) ) ;
138+
139+ assert_ok ! ( <orml_tokens:: Pallet <T >>:: deposit(
140+ get_collateral_currency_id:: <T >( ) ,
141+ & vault_id. account_id,
142+ ( 1u32 << 31 ) . into( )
143+ ) ) ;
144+ assert_ok ! ( <orml_tokens:: Pallet <T >>:: deposit(
145+ get_native_currency_id:: <T >( ) ,
146+ & vault_id. account_id,
147+ ( 1u32 << 31 ) . into( )
148+ ) ) ;
149+
150+ assert_ok ! ( VaultRegistry :: <T >:: register_public_key(
151+ origin. into( ) ,
152+ BtcPublicKey :: dummy( )
153+ ) ) ;
154+ assert_ok ! ( VaultRegistry :: <T >:: _register_vault(
155+ vault_id. clone( ) ,
156+ 100000000u32 . into( )
157+ ) ) ;
158+
159+ VaultRegistry :: < T > :: try_increase_to_be_issued_tokens ( vault_id, & issued_tokens) . unwrap ( ) ;
160+ VaultRegistry :: < T > :: issue_tokens ( vault_id, & issued_tokens) . unwrap ( ) ;
161+ }
162+
163+ struct ChainState < T : Config > {
164+ old_vault_id : DefaultVaultId < T > ,
165+ new_vault_id : DefaultVaultId < T > ,
166+ issued_tokens : Amount < T > ,
167+ to_be_replaced : Amount < T > ,
168+ }
169+
170+ fn setup_chain < T : crate :: Config > ( ) -> ChainState < T > {
171+ let new_vault_id = get_vault_id :: < T > ( "NewVault" ) ;
172+ let old_vault_id = get_vault_id :: < T > ( "OldVault" ) ;
173+
174+ Oracle :: < T > :: _set_exchange_rate (
175+ get_native_currency_id :: < T > ( ) , // for griefing collateral
176+ <T as currency:: Config >:: UnsignedFixedPoint :: one ( ) ,
177+ )
178+ . unwrap ( ) ;
179+ Oracle :: < T > :: _set_exchange_rate (
180+ old_vault_id. collateral_currency ( ) ,
181+ <T as currency:: Config >:: UnsignedFixedPoint :: one ( ) ,
182+ )
183+ . unwrap ( ) ;
184+
185+ VaultRegistry :: < T > :: set_minimum_collateral (
186+ RawOrigin :: Root . into ( ) ,
187+ old_vault_id. collateral_currency ( ) ,
188+ 100_000u32 . into ( ) ,
189+ )
190+ . unwrap ( ) ;
191+ VaultRegistry :: < T > :: _set_system_collateral_ceiling ( old_vault_id. currencies . clone ( ) , 1_000_000_000u32 . into ( ) ) ;
192+
193+ VaultRegistry :: < T > :: _set_secure_collateral_threshold (
194+ old_vault_id. currencies . clone ( ) ,
195+ <T as currency:: Config >:: UnsignedFixedPoint :: checked_from_rational ( 1 , 100000 ) . unwrap ( ) ,
196+ ) ;
197+ VaultRegistry :: < T > :: _set_premium_redeem_threshold (
198+ old_vault_id. currencies . clone ( ) ,
199+ <T as currency:: Config >:: UnsignedFixedPoint :: checked_from_rational ( 1 , 200000 ) . unwrap ( ) ,
200+ ) ;
201+ VaultRegistry :: < T > :: _set_liquidation_collateral_threshold (
202+ old_vault_id. currencies . clone ( ) ,
203+ <T as currency:: Config >:: UnsignedFixedPoint :: checked_from_rational ( 1 , 300000 ) . unwrap ( ) ,
204+ ) ;
205+
206+ let issued_tokens = Amount :: new ( 200000u32 . into ( ) , old_vault_id. wrapped_currency ( ) ) ;
207+ let to_be_replaced = issued_tokens. clone ( ) . map ( |x| x / 4u32 . into ( ) ) ;
208+
209+ register_vault ( & old_vault_id, issued_tokens. clone ( ) ) ;
210+ register_vault ( & new_vault_id, issued_tokens. clone ( ) ) ;
211+
212+ ChainState {
213+ old_vault_id,
214+ new_vault_id,
215+ issued_tokens,
216+ to_be_replaced,
217+ }
218+ }
219+
220+ fn setup_replace < T : crate :: Config > (
221+ old_vault_id : & DefaultVaultId < T > ,
222+ new_vault_id : & DefaultVaultId < T > ,
223+ to_be_replaced : Amount < T > ,
224+ ) -> ( H256 , BalanceOf < T > )
225+ where
226+ <<T as currency:: Config >:: Balance as TryInto < i64 > >:: Error : Debug ,
227+ {
228+ let value: Amount < T > = Amount :: new ( 2u32 . into ( ) , get_wrapped_currency_id :: < T > ( ) ) ;
229+
230+ //set up redeem
231+ let redeem_id = H256 :: zero ( ) ;
232+ let mut redeem_request = test_request :: < T > ( & old_vault_id) ;
233+ redeem_request. redeemer = new_vault_id. account_id . clone ( ) ;
234+ redeem_request. opentime = Security :: < T > :: active_block_number ( ) ;
235+ redeem_request. issue_id = Some ( H256 :: zero ( ) ) ;
236+ redeem_request. amount_btc = value. amount ( ) ;
237+ Redeem :: < T > :: insert_redeem_request ( & redeem_id, & redeem_request) ;
238+
239+ VaultRegistry :: < T > :: try_increase_to_be_redeemed_tokens ( & old_vault_id, & to_be_replaced) . unwrap ( ) ;
240+ VaultRegistry :: < T > :: try_increase_to_be_issued_tokens ( & new_vault_id, & to_be_replaced) . unwrap ( ) ;
241+
242+ mint_and_reserve_wrapped :: < T > ( & redeem_request. redeemer , redeem_request. amount_btc ) ;
243+
244+ // expire redeem request
245+ initialize_and_mine_blocks_until_expiry :: < T > ( & redeem_request) ;
246+ Security :: < T > :: set_active_block_number (
247+ Security :: < T > :: active_block_number ( ) + Redeem :: < T > :: redeem_period ( ) + 100u32 . into ( ) ,
248+ ) ;
249+
250+ // set up issue
251+ let issue_id = H256 :: zero ( ) ;
252+ let issue_request = IssueRequest {
253+ requester : AccountOrVault :: Account ( old_vault_id. account_id . clone ( ) ) ,
254+ vault : new_vault_id. clone ( ) ,
255+ btc_address : Default :: default ( ) ,
256+ amount : value. amount ( ) ,
257+ btc_height : Default :: default ( ) ,
258+ btc_public_key : Default :: default ( ) ,
259+ fee : Default :: default ( ) ,
260+ griefing_collateral : Default :: default ( ) ,
261+ griefing_currency : get_native_currency_id :: < T > ( ) ,
262+ opentime : Default :: default ( ) ,
263+ period : Default :: default ( ) ,
264+ status : Default :: default ( ) ,
265+ } ;
266+ Issue :: < T > :: insert_issue_request ( & issue_id, & issue_request) ;
267+ let value: Amount < T > = Amount :: new ( 3u32 . into ( ) , get_wrapped_currency_id :: < T > ( ) ) ;
268+
269+ VaultRegistry :: < T > :: try_increase_to_be_issued_tokens ( & new_vault_id, & value) . unwrap ( ) ;
270+
271+ Redeem :: < T > :: insert_request ( & redeem_id, & issue_id) ;
272+
273+ ( redeem_id, redeem_request. amount_btc )
274+ }
275+
126276#[ benchmarks(
127277 where
128278 T : loans:: Config ,
@@ -333,6 +483,44 @@ pub mod benchmarks {
333483 cancel_redeem ( RawOrigin :: Signed ( caller) , redeem_id, false ) ;
334484 }
335485
486+ #[ benchmark]
487+ pub fn cancel_replace ( ) {
488+ let ChainState {
489+ old_vault_id,
490+ to_be_replaced,
491+ new_vault_id,
492+ ..
493+ } = setup_chain :: < T > ( ) ;
494+
495+ let ( redeem_id, amount_btc) = setup_replace :: < T > ( & old_vault_id, & new_vault_id, to_be_replaced) ;
496+
497+ let vault_id = activate_lending_and_get_vault_id :: < T > ( ) ;
498+
499+ initialize_oracle :: < T > ( ) ;
500+
501+ register_public_key :: < T > ( vault_id. clone ( ) ) ;
502+ VaultRegistry :: < T > :: insert_vault (
503+ & vault_id,
504+ Vault {
505+ id : vault_id. clone ( ) ,
506+ issued_tokens : amount_btc,
507+ to_be_redeemed_tokens : amount_btc,
508+ ..Vault :: new ( vault_id. clone ( ) )
509+ } ,
510+ ) ;
511+
512+ mint_collateral :: < T > ( & vault_id. account_id , 1000u32 . into ( ) ) ;
513+ assert_ok ! ( VaultRegistry :: <T >:: try_deposit_collateral( & vault_id, & collateral( 1000 ) ) ) ;
514+
515+ assert_ok ! ( Oracle :: <T >:: _set_exchange_rate(
516+ get_collateral_currency_id:: <T >( ) ,
517+ UnsignedFixedPoint :: <T >:: one( )
518+ ) ) ;
519+
520+ #[ extrinsic_call]
521+ cancel_redeem ( RawOrigin :: Signed ( old_vault_id. account_id . clone ( ) ) , redeem_id, true ) ;
522+ }
523+
336524 #[ benchmark]
337525 pub fn set_redeem_period ( ) {
338526 #[ extrinsic_call]
@@ -376,6 +564,43 @@ pub mod benchmarks {
376564 _ ( RawOrigin :: Signed ( caller) , vault_id. currencies , amount. into ( ) ) ;
377565 }
378566
567+ #[ benchmark]
568+ pub fn request_replace ( ) {
569+ let ChainState {
570+ old_vault_id,
571+ issued_tokens,
572+ to_be_replaced,
573+ new_vault_id,
574+ } = setup_chain :: < T > ( ) ;
575+ let amount = ( issued_tokens. checked_sub ( & to_be_replaced) . unwrap ( ) ) . amount ( ) ;
576+ let relayer_id: T :: AccountId = account ( "Relayer" , 0 , 0 ) ;
577+ initialize_oracle :: < T > ( ) ;
578+ mint_collateral :: < T > ( & relayer_id, ( 1u32 << 31 ) . into ( ) ) ;
579+
580+ // initialize relay
581+ let init_block = BlockBuilder :: new ( )
582+ . with_version ( 4 )
583+ . with_coinbase ( & BtcAddress :: dummy ( ) , 50 , 3 )
584+ . with_timestamp ( u32:: MAX )
585+ . mine ( U256 :: from ( 2 ) . pow ( 254 . into ( ) ) )
586+ . unwrap ( ) ;
587+
588+ BtcRelay :: < T > :: _initialize ( relayer_id. clone ( ) , init_block. header , 0 ) . unwrap ( ) ;
589+ BtcRelay :: < T > :: mine_blocks ( & relayer_id, 1 ) ;
590+ Security :: < T > :: set_active_block_number (
591+ Security :: < T > :: active_block_number ( ) + BtcRelay :: < T > :: parachain_confirmations ( ) ,
592+ ) ;
593+
594+ #[ extrinsic_call]
595+ _ (
596+ RawOrigin :: Signed ( old_vault_id. account_id . clone ( ) ) ,
597+ old_vault_id. currencies . clone ( ) ,
598+ amount,
599+ new_vault_id. clone ( ) ,
600+ get_native_currency_id :: < T > ( ) ,
601+ ) ;
602+ }
603+
379604 impl_benchmark_test_suite ! (
380605 Redeem ,
381606 crate :: mock:: ExtBuilder :: build_with( Default :: default ( ) ) ,
0 commit comments