@@ -5,9 +5,9 @@ use ic_cdk_macros::{init, post_upgrade, query, update};
55use rumi_protocol_backend:: {
66 event:: Event ,
77 logs:: INFO ,
8- numeric:: { ICUSD , UsdIcp } ,
8+ numeric:: { ICUSD , UsdIcp , UsdCkBtc } ,
99 state:: { read_state, replace_state, Mode , State } ,
10- vault:: { CandidVault , OpenVaultSuccess , VaultArg } ,
10+ vault:: { CandidVault , OpenVaultSuccess , VaultArg , CollateralType } ,
1111 Fees , GetEventsArg , ProtocolArg , ProtocolError , ProtocolStatus , SuccessWithFee ,
1212} ;
1313use rumi_protocol_backend:: logs:: DEBUG ;
@@ -23,7 +23,6 @@ use rumi_protocol_backend::LiquidityStatus;
2323use candid_parser:: utils:: CandidSource ;
2424use candid_parser:: utils:: service_equal;
2525
26-
2726#[ cfg( feature = "self_check" ) ]
2827fn ok_or_die ( result : Result < ( ) , String > ) {
2928 if let Err ( msg) = result {
@@ -81,9 +80,15 @@ fn validate_mode() -> Result<(), ProtocolError> {
8180}
8281
8382fn setup_timers ( ) {
83+ // Existing ICP rate fetching timer
8484 ic_cdk_timers:: set_timer_interval ( rumi_protocol_backend:: xrc:: FETCHING_ICP_RATE_INTERVAL , || {
8585 ic_cdk:: spawn ( rumi_protocol_backend:: xrc:: fetch_icp_rate ( ) )
8686 } ) ;
87+
88+ // New ckBTC rate fetching timer
89+ ic_cdk_timers:: set_timer_interval ( rumi_protocol_backend:: xrc:: FETCHING_CKBTC_RATE_INTERVAL , || {
90+ ic_cdk:: spawn ( rumi_protocol_backend:: xrc:: fetch_ckbtc_rate ( ) )
91+ } ) ;
8792}
8893
8994fn main ( ) { }
@@ -156,7 +161,13 @@ fn get_protocol_status() -> ProtocolStatus {
156161 . unwrap_or ( UsdIcp :: from ( Decimal :: ZERO ) )
157162 . to_f64 ( ) ,
158163 last_icp_timestamp : s. last_icp_timestamp . unwrap_or ( 0 ) ,
164+ last_ckbtc_rate : s
165+ . last_ckbtc_rate
166+ . unwrap_or ( UsdCkBtc :: from ( Decimal :: ZERO ) )
167+ . to_f64 ( ) ,
168+ last_ckbtc_timestamp : s. last_ckbtc_timestamp . unwrap_or ( 0 ) ,
159169 total_icp_margin : s. total_icp_margin_amount ( ) . to_u64 ( ) ,
170+ total_ckbtc_margin : s. total_ckbtc_margin_amount ( ) . to_u64 ( ) ,
160171 total_icusd_borrowed : s. total_borrowed_icusd_amount ( ) . to_u64 ( ) ,
161172 total_collateral_ratio : s. total_collateral_ratio . to_f64 ( ) ,
162173 mode : s. mode ,
@@ -235,7 +246,9 @@ fn get_vaults(target: Option<Principal>) -> Vec<CandidVault> {
235246 owner : vault. owner ,
236247 borrowed_icusd_amount : vault. borrowed_icusd_amount . to_u64 ( ) ,
237248 icp_margin_amount : vault. icp_margin_amount . to_u64 ( ) ,
249+ ckbtc_margin_amount : vault. ckbtc_margin_amount . to_u64 ( ) ,
238250 vault_id : vault. vault_id ,
251+ collateral_type : vault. collateral_type ,
239252 }
240253 } )
241254 . collect ( ) ,
@@ -248,7 +261,9 @@ fn get_vaults(target: Option<Principal>) -> Vec<CandidVault> {
248261 owner : vault. owner ,
249262 borrowed_icusd_amount : vault. borrowed_icusd_amount . to_u64 ( ) ,
250263 icp_margin_amount : vault. icp_margin_amount . to_u64 ( ) ,
264+ ckbtc_margin_amount : vault. ckbtc_margin_amount . to_u64 ( ) ,
251265 vault_id : vault. vault_id ,
266+ collateral_type : vault. collateral_type ,
252267 } )
253268 . collect :: < Vec < CandidVault > > ( )
254269 } ) ,
@@ -275,9 +290,9 @@ fn get_redemption_rate() -> f64 {
275290
276291#[ candid_method( update) ]
277292#[ update]
278- async fn open_vault ( icp_margin : u64 ) -> Result < OpenVaultSuccess , ProtocolError > {
293+ async fn open_vault ( collateral_amount : u64 , collateral_type : CollateralType ) -> Result < OpenVaultSuccess , ProtocolError > {
279294 validate_call ( ) ?;
280- check_postcondition ( rumi_protocol_backend:: vault:: open_vault ( icp_margin ) . await )
295+ check_postcondition ( rumi_protocol_backend:: vault:: open_vault ( collateral_amount , collateral_type ) . await )
281296}
282297
283298#[ candid_method( update) ]
@@ -338,31 +353,45 @@ async fn liquidate_vault(vault_id: u64) -> Result<SuccessWithFee, ProtocolError>
338353fn get_liquidatable_vaults ( ) -> Vec < CandidVault > {
339354 read_state ( |s| {
340355 let current_icp_rate = s. last_icp_rate . unwrap_or ( UsdIcp :: from ( dec ! ( 0.0 ) ) ) ;
356+ let current_ckbtc_rate = s. last_ckbtc_rate . unwrap_or ( UsdCkBtc :: from ( dec ! ( 0.0 ) ) ) ;
341357
342- if current_icp_rate. to_f64 ( ) == 0.0 {
358+ if current_icp_rate. to_f64 ( ) == 0.0 && current_ckbtc_rate . to_f64 ( ) == 0.0 {
343359 return vec ! [ ] ;
344360 }
345361
346362 s. vault_id_to_vaults
347363 . values ( )
348364 . filter ( |vault| {
349- let ratio = rumi_protocol_backend:: compute_collateral_ratio ( vault, current_icp_rate) ;
365+ let ratio = match vault. collateral_type {
366+ CollateralType :: ICP => {
367+ if current_icp_rate. to_f64 ( ) == 0.0 { return false ; }
368+ rumi_protocol_backend:: compute_collateral_ratio ( vault, current_icp_rate, CollateralType :: ICP )
369+ } ,
370+ CollateralType :: CkBTC => {
371+ if current_ckbtc_rate. to_f64 ( ) == 0.0 { return false ; }
372+ rumi_protocol_backend:: compute_collateral_ratio ( vault, current_ckbtc_rate, CollateralType :: CkBTC )
373+ }
374+ } ;
350375 ratio < s. mode . get_minimum_liquidation_collateral_ratio ( )
351376 } )
352377 . map ( |vault| {
353- let collateral_ratio = rumi_protocol_backend:: compute_collateral_ratio ( vault, current_icp_rate) ;
378+ let collateral_ratio = match vault. collateral_type {
379+ CollateralType :: ICP => rumi_protocol_backend:: compute_collateral_ratio ( vault, current_icp_rate, CollateralType :: ICP ) ,
380+ CollateralType :: CkBTC => rumi_protocol_backend:: compute_collateral_ratio ( vault, current_ckbtc_rate, CollateralType :: CkBTC ) ,
381+ } ;
354382 CandidVault {
355383 owner : vault. owner ,
356384 borrowed_icusd_amount : vault. borrowed_icusd_amount . to_u64 ( ) ,
357385 icp_margin_amount : vault. icp_margin_amount . to_u64 ( ) ,
386+ ckbtc_margin_amount : vault. ckbtc_margin_amount . to_u64 ( ) ,
358387 vault_id : vault. vault_id ,
388+ collateral_type : vault. collateral_type ,
359389 }
360390 } )
361391 . collect :: < Vec < CandidVault > > ( )
362392 } )
363393}
364394
365-
366395// Liquidity related operations
367396#[ candid_method( update) ]
368397#[ update]
@@ -457,21 +486,38 @@ fn http_request(req: HttpRequest) -> HttpResponse {
457486 "ICP rate." ,
458487 ) ?;
459488
489+ w. encode_gauge (
490+ "rumi_ckbtc_rate" ,
491+ s. last_ckbtc_rate . unwrap_or ( UsdCkBtc :: from ( dec ! ( 0 ) ) ) . to_f64 ( ) ,
492+ "ckBTC rate." ,
493+ ) ?;
494+
460495 let total_icp_dec = Decimal :: from_u64 ( s. total_icp_margin_amount ( ) . 0 )
461496 . expect ( "failed to construct decimal from u64" )
462497 / dec ! ( 100_000_000 ) ;
463498
499+ let total_ckbtc_dec = Decimal :: from_u64 ( s. total_ckbtc_margin_amount ( ) . 0 )
500+ . expect ( "failed to construct decimal from u64" )
501+ / dec ! ( 100_000_000 ) ;
502+
464503 w. encode_gauge (
465504 "icp_total_ICP_margin" ,
466505 total_icp_dec. to_f64 ( ) . unwrap ( ) ,
467506 "Total ICP Margin." ,
468507 ) ?;
469508
470509 w. encode_gauge (
471- "ICP_total_tvl" ,
472- ( total_icp_dec * s. last_icp_rate . unwrap_or ( UsdIcp :: from ( dec ! ( 0 ) ) ) . 0 )
473- . to_f64 ( )
474- . unwrap ( ) ,
510+ "ckbtc_total_CKBTC_margin" ,
511+ total_ckbtc_dec. to_f64 ( ) . unwrap ( ) ,
512+ "Total ckBTC Margin." ,
513+ ) ?;
514+
515+ let total_tvl = ( total_icp_dec * s. last_icp_rate . unwrap_or ( UsdIcp :: from ( dec ! ( 0 ) ) ) . 0 )
516+ + ( total_ckbtc_dec * s. last_ckbtc_rate . unwrap_or ( UsdCkBtc :: from ( dec ! ( 0 ) ) ) . 0 ) ;
517+
518+ w. encode_gauge (
519+ "total_tvl" ,
520+ total_tvl. to_f64 ( ) . unwrap ( ) ,
475521 "Total TVL." ,
476522 ) ?;
477523
@@ -486,7 +532,7 @@ fn http_request(req: HttpRequest) -> HttpResponse {
486532 ) ?;
487533
488534 w. encode_gauge (
489- "ICP_total_collateral_ratio " ,
535+ "total_collateral_ratio " ,
490536 s. total_collateral_ratio . to_f64 ( ) ,
491537 "TCR." ,
492538 ) ?;
@@ -597,14 +643,27 @@ async fn recover_pending_transfer(vault_id: u64) -> Result<bool, ProtocolError>
597643 } ) ;
598644
599645 if let Some ( transfer) = transfer_opt {
600- let icp_transfer_fee = read_state ( |s| s. icp_ledger_fee ) ;
646+ let transfer_fee = match transfer. collateral_type {
647+ CollateralType :: ICP => read_state ( |s| s. icp_ledger_fee ) ,
648+ CollateralType :: CkBTC => read_state ( |s| s. ckbtc_ledger_fee ) ,
649+ } ;
601650
602- match crate :: management:: transfer_icp (
603- transfer. margin - icp_transfer_fee,
604- transfer. owner ,
605- )
606- . await
607- {
651+ let result = match transfer. collateral_type {
652+ CollateralType :: ICP => {
653+ crate :: management:: transfer_icp (
654+ transfer. margin - transfer_fee,
655+ transfer. owner ,
656+ ) . await
657+ } ,
658+ CollateralType :: CkBTC => {
659+ crate :: management:: transfer_ckbtc (
660+ transfer. margin - transfer_fee,
661+ transfer. owner ,
662+ ) . await
663+ }
664+ } ;
665+
666+ match result {
608667 Ok ( block_index) => {
609668 mutate_state ( |s| crate :: event:: record_margin_transfer ( s, vault_id, block_index) ) ;
610669 Ok ( true )
@@ -637,7 +696,6 @@ fn check_candid_interface_compatibility() {
637696 }
638697 }
639698
640-
641699 fn check_service_compatible (
642700 new_name : & str ,
643701 new : CandidSource ,
0 commit comments