@@ -61,12 +61,15 @@ pub struct BorrowPosition {
6161 pub started_at_block_timestamp_ms : Option < U64 > ,
6262 pub collateral_asset_deposit : CollateralAssetAmount ,
6363 borrow_asset_principal : BorrowAssetAmount ,
64+ #[ serde( alias = "borrow_asset_fees" ) ]
6465 pub interest : Accumulator < BorrowAsset > ,
66+ #[ serde( default ) ]
6567 pub fees : BorrowAssetAmount ,
6668 #[ serde( default ) ]
6769 borrow_asset_in_flight : BorrowAssetAmount ,
6870 #[ serde( default ) ]
6971 collateral_asset_in_flight : CollateralAssetAmount ,
72+ #[ serde( default ) ]
7073 pub liquidation_lock : CollateralAssetAmount ,
7174}
7275
@@ -811,3 +814,121 @@ impl<'a> BorrowPositionGuard<'a> {
811814 . emit ( ) ;
812815 }
813816}
817+
818+ #[ cfg( test) ]
819+ mod tests {
820+ use super :: * ;
821+ use near_sdk:: serde_json;
822+
823+ #[ test]
824+ fn test_borrow_position_deserialize_new_format ( ) {
825+ // New market format with interest field
826+ let json = r#"{
827+ "started_at_block_timestamp_ms": "1699564800000",
828+ "collateral_asset_deposit": "1000000000000000000000000",
829+ "borrow_asset_principal": "100000000",
830+ "interest": {
831+ "total": "0",
832+ "fraction_as_u128_dividend": "0",
833+ "next_snapshot_index": 42,
834+ "pending_estimate": "0"
835+ },
836+ "fees": "500000",
837+ "borrow_asset_in_flight": "50000000",
838+ "collateral_asset_in_flight": "0",
839+ "liquidation_lock": "0"
840+ }"# ;
841+
842+ let position: BorrowPosition =
843+ serde_json:: from_str ( json) . expect ( "Failed to deserialize new format" ) ;
844+ assert_eq ! ( position. fees, BorrowAssetAmount :: new( 500_000 ) ) ;
845+ assert_eq ! (
846+ position. get_borrow_asset_principal( ) ,
847+ BorrowAssetAmount :: new( 50_000_000 + 100_000_000 )
848+ ) ;
849+ }
850+
851+ #[ test]
852+ fn test_borrow_position_deserialize_old_format_with_borrow_asset_fees ( ) {
853+ // Old market format with borrow_asset_fees instead of interest
854+ let json = r#"{
855+ "started_at_block_timestamp_ms": "1699564800000",
856+ "collateral_asset_deposit": "1000000000000000000000000",
857+ "borrow_asset_principal": "100000000",
858+ "borrow_asset_fees": {
859+ "total": "0",
860+ "fraction_as_u128_dividend": "0",
861+ "next_snapshot_index": 42,
862+ "pending_estimate": "0"
863+ },
864+ "fees": "500000",
865+ "borrow_asset_in_flight": "0",
866+ "collateral_asset_in_flight": "0",
867+ "liquidation_lock": "0"
868+ }"# ;
869+
870+ let position: BorrowPosition =
871+ serde_json:: from_str ( json) . expect ( "Failed to deserialize old format" ) ;
872+ assert_eq ! ( position. fees, BorrowAssetAmount :: new( 500_000 ) ) ;
873+ assert_eq ! (
874+ position. get_borrow_asset_principal( ) ,
875+ BorrowAssetAmount :: new( 100_000_000 )
876+ ) ;
877+ }
878+
879+ #[ test]
880+ fn test_borrow_position_deserialize_mixed_old_new_format ( ) {
881+ // Mixed format: old field name for interest (borrow_asset_fees), new field names for others
882+ let json = r#"{
883+ "started_at_block_timestamp_ms": "1699564800000",
884+ "collateral_asset_deposit": "1000000000000000000000000",
885+ "borrow_asset_principal": "100000000",
886+ "borrow_asset_fees": {
887+ "total": "0",
888+ "fraction_as_u128_dividend": "0",
889+ "next_snapshot_index": 42,
890+ "pending_estimate": "0"
891+ },
892+ "fees": "500000",
893+ "borrow_asset_in_flight": "0",
894+ "collateral_asset_in_flight": "0",
895+ "liquidation_lock": "0"
896+ }"# ;
897+
898+ let position: BorrowPosition =
899+ serde_json:: from_str ( json) . expect ( "Failed to deserialize mixed format" ) ;
900+ assert_eq ! ( position. fees, BorrowAssetAmount :: new( 500_000 ) ) ;
901+ assert_eq ! (
902+ position. get_borrow_asset_principal( ) ,
903+ BorrowAssetAmount :: new( 100_000_000 )
904+ ) ;
905+ assert_eq ! (
906+ position. get_total_collateral_amount( ) ,
907+ CollateralAssetAmount :: new( 1_000_000_000_000_000_000_000_000 )
908+ ) ;
909+ }
910+
911+ #[ test]
912+ fn test_borrow_position_deserialize_defaults ( ) {
913+ // Minimal JSON with only required fields, others should use defaults
914+ let json = r#"{
915+ "collateral_asset_deposit": "1000000000000000000000000",
916+ "borrow_asset_principal": "100000000",
917+ "interest": {
918+ "total": "0",
919+ "fraction_as_u128_dividend": "0",
920+ "next_snapshot_index": 42,
921+ "pending_estimate": "0"
922+ }
923+ }"# ;
924+
925+ let position: BorrowPosition =
926+ serde_json:: from_str ( json) . expect ( "Failed to deserialize with defaults" ) ;
927+ assert_eq ! ( position. started_at_block_timestamp_ms, None ) ;
928+ assert_eq ! ( position. fees, BorrowAssetAmount :: new( 0 ) ) ;
929+ assert_eq ! (
930+ position. get_total_collateral_amount( ) ,
931+ CollateralAssetAmount :: new( 1_000_000_000_000_000_000_000_000 )
932+ ) ;
933+ }
934+ }
0 commit comments