Skip to content

Commit ef0f85b

Browse files
authored
Fix: market deserialization error for interest and fees fields. (#288)
* Fix: market deserialization error for interest and fees fileds. * Add test * Add test * Add alias for interest instead of default
1 parent 46ec669 commit ef0f85b

File tree

1 file changed

+121
-0
lines changed

1 file changed

+121
-0
lines changed

common/src/borrow.rs

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)