use crate::contract::{execute, instantiate, query};
use crate::testing::mock_querier::mock_dependencies;
use cosmwasm_std::testing::{mock_env, mock_info};
use cosmwasm_std::{from_json, to_json_binary, Decimal256, Uint128, Uint256};
use cw20::Cw20ReceiveMsg;
use solid_moneymarket::liquidation_queue::{
BidPoolResponse, BidPoolsResponse, BidResponse, BidsResponse, CollateralInfoResponse,
Cw20HookMsg, ExecuteMsg, InstantiateMsg, LiquidationAmountResponse, QueryMsg,
};
#[test]
fn query_liquidation_amount() {
let mut deps = mock_dependencies(&[]);
deps.querier.with_collateral_max_ltv(&[
(&"token0000".to_string(), &Decimal256::percent(50)),
(&"token0001".to_string(), &Decimal256::percent(50)),
(&"token0002".to_string(), &Decimal256::percent(50)),
]);
let msg = InstantiateMsg {
owner: "owner0000".to_string(),
oracle_contract: "oracle0000".to_string(),
stable_contract: "stable0000".to_string(),
safe_ratio: Decimal256::percent(10),
bid_fee: Decimal256::percent(1),
liquidator_fee: Decimal256::percent(0),
liquidation_threshold: Uint256::from(100000000u64),
price_timeframe: 60u64,
waiting_period: 60u64,
overseer: "overseer0000".to_string(),
};
let info = mock_info("addr0000", &[]);
let _res = instantiate(deps.as_mut(), mock_env(), info, msg).unwrap();
let msg = ExecuteMsg::WhitelistCollateral {
collateral_token: "token0000".to_string(),
max_slot: 30u8,
bid_threshold: Uint256::from(10000u128), premium_rate_per_slot: Decimal256::percent(1),
};
let info = mock_info("owner0000", &[]);
execute(deps.as_mut(), mock_env(), info.clone(), msg).unwrap();
let msg = ExecuteMsg::WhitelistCollateral {
collateral_token: "token0001".to_string(),
max_slot: 30u8,
bid_threshold: Uint256::from(10000u128), premium_rate_per_slot: Decimal256::percent(1),
};
execute(deps.as_mut(), mock_env(), info.clone(), msg).unwrap();
let msg = ExecuteMsg::WhitelistCollateral {
collateral_token: "token0002".to_string(),
max_slot: 30u8,
bid_threshold: Uint256::from(10000u128), premium_rate_per_slot: Decimal256::percent(1),
};
execute(deps.as_mut(), mock_env(), info, msg).unwrap();
let info = mock_info("stable0000", &[]);
let msg = ExecuteMsg::Receive(Cw20ReceiveMsg {
sender: "addr0000".to_string(),
amount: Uint128::from(100000000000u128),
msg: to_json_binary(&Cw20HookMsg::SubmitBid {
collateral_token: "token0000".to_string(),
premium_slot: 5u8,
})
.unwrap(),
});
execute(deps.as_mut(), mock_env(), info.clone(), msg).unwrap();
let msg = ExecuteMsg::Receive(Cw20ReceiveMsg {
sender: "addr0000".to_string(),
amount: Uint128::from(100000000000u128),
msg: to_json_binary(&Cw20HookMsg::SubmitBid {
collateral_token: "token0001".to_string(),
premium_slot: 5u8,
})
.unwrap(),
});
execute(deps.as_mut(), mock_env(), info.clone(), msg).unwrap();
let msg = ExecuteMsg::Receive(Cw20ReceiveMsg {
sender: "addr0000".to_string(),
amount: Uint128::from(100000000000u128),
msg: to_json_binary(&Cw20HookMsg::SubmitBid {
collateral_token: "token0002".to_string(),
premium_slot: 5u8,
})
.unwrap(),
});
execute(deps.as_mut(), mock_env(), info, msg).unwrap();
let msg = QueryMsg::LiquidationAmount {
borrow_amount: Uint256::from(931095u64),
borrow_limit: Uint256::from(900000u64),
collaterals: vec![("token0000".to_string(), Uint256::from(1000000u64))],
collateral_prices: vec![Decimal256::percent(10)],
};
let res = query(deps.as_ref(), mock_env(), msg).unwrap();
let res: LiquidationAmountResponse = from_json(&res).unwrap();
assert_eq!(
res,
LiquidationAmountResponse {
collaterals: vec![("token0000".to_string(), Uint256::from(1000000u64))],
}
);
let msg = QueryMsg::LiquidationAmount {
borrow_amount: Uint256::from(100000u64),
borrow_limit: Uint256::from(1000000u64),
collaterals: vec![("token0000".to_string(), Uint256::from(1000000u64))],
collateral_prices: vec![Decimal256::one()],
};
let res = query(deps.as_ref(), mock_env(), msg).unwrap();
let res: LiquidationAmountResponse = from_json(&res).unwrap();
assert_eq!(
res,
LiquidationAmountResponse {
collaterals: vec![],
}
);
let query_msg = QueryMsg::LiquidationAmount {
borrow_amount: Uint256::from(1000000u64),
borrow_limit: Uint256::from(99999u64),
collaterals: vec![
("token0000".to_string(), Uint256::from(1000000u64)),
("token0001".to_string(), Uint256::from(2000000u64)),
("token0002".to_string(), Uint256::from(3000000u64)),
],
collateral_prices: vec![
Decimal256::percent(50),
Decimal256::percent(50),
Decimal256::percent(50),
],
};
let res = query(deps.as_ref(), mock_env(), query_msg).unwrap();
let res: LiquidationAmountResponse = from_json(&res).unwrap();
assert_eq!(
res,
LiquidationAmountResponse {
collaterals: vec![
("token0000".to_string(), Uint256::from(354420u64)),
("token0001".to_string(), Uint256::from(708843u64)),
("token0002".to_string(), Uint256::from(1063265u64)),
],
}
);
}
#[test]
fn query_bids() {
let mut deps = mock_dependencies(&[]);
deps.querier
.with_collateral_max_ltv(&[(&"token0000".to_string(), &Decimal256::percent(90))]);
let msg = InstantiateMsg {
owner: "owner0000".to_string(),
oracle_contract: "oracle0000".to_string(),
stable_contract: "stable0000".to_string(),
safe_ratio: Decimal256::percent(10),
bid_fee: Decimal256::percent(1),
liquidator_fee: Decimal256::percent(0),
liquidation_threshold: Uint256::from(100000000u64),
price_timeframe: 60u64,
waiting_period: 60u64,
overseer: "overseer0000".to_string(),
};
let info = mock_info("addr0000", &[]);
let _res = instantiate(deps.as_mut(), mock_env(), info, msg).unwrap();
let msg = ExecuteMsg::WhitelistCollateral {
collateral_token: "token0000".to_string(),
max_slot: 30u8,
bid_threshold: Uint256::from(10000u128), premium_rate_per_slot: Decimal256::percent(1),
};
let info = mock_info("owner0000", &[]);
execute(deps.as_mut(), mock_env(), info, msg).unwrap();
let info = mock_info("stable0000", &[]);
let msg = ExecuteMsg::Receive(Cw20ReceiveMsg {
sender: "addr0000".to_string(),
amount: Uint128::from(1000u128),
msg: to_json_binary(&Cw20HookMsg::SubmitBid {
collateral_token: "token0000".to_string(),
premium_slot: 5u8,
})
.unwrap(),
});
execute(deps.as_mut(), mock_env(), info.clone(), msg).unwrap();
let msg = ExecuteMsg::Receive(Cw20ReceiveMsg {
sender: "addr0000".to_string(),
amount: Uint128::from(1000u128),
msg: to_json_binary(&Cw20HookMsg::SubmitBid {
collateral_token: "token0000".to_string(),
premium_slot: 5u8,
})
.unwrap(),
});
execute(deps.as_mut(), mock_env(), info.clone(), msg).unwrap();
let msg = ExecuteMsg::Receive(Cw20ReceiveMsg {
sender: "addr0000".to_string(),
amount: Uint128::from(1000u128),
msg: to_json_binary(&Cw20HookMsg::SubmitBid {
collateral_token: "token0000".to_string(),
premium_slot: 10u8,
})
.unwrap(),
});
execute(deps.as_mut(), mock_env(), info, msg).unwrap();
let bid_response: BidResponse = from_json(
&query(
deps.as_ref(),
mock_env(),
QueryMsg::Bid {
bid_idx: Uint128::from(1u128),
},
)
.unwrap(),
)
.unwrap();
assert_eq!(
bid_response,
BidResponse {
idx: Uint128::from(1u128),
collateral_token: "token0000".to_string(),
bidder: "addr0000".to_string(),
amount: Uint256::from(1000u128),
premium_slot: 5u8,
pending_liquidated_collateral: Uint256::zero(),
wait_end: None,
product_snapshot: Decimal256::from_ratio(Decimal256::one().atomics(), Uint256::one()),
sum_snapshot: Decimal256::zero(),
epoch_snapshot: Uint128::zero(),
scale_snapshot: Uint128::zero(),
}
);
let bids_response: BidsResponse = from_json(
&query(
deps.as_ref(),
mock_env(),
QueryMsg::BidsByUser {
collateral_token: "token0000".to_string(),
bidder: "addr0000".to_string(),
start_after: None,
limit: None,
},
)
.unwrap(),
)
.unwrap();
assert_eq!(
bids_response,
BidsResponse {
bids: vec![
BidResponse {
idx: Uint128::from(1u128),
collateral_token: "token0000".to_string(),
bidder: "addr0000".to_string(),
amount: Uint256::from(1000u128),
premium_slot: 5u8,
pending_liquidated_collateral: Uint256::zero(),
wait_end: None,
product_snapshot: Decimal256::from_ratio(Decimal256::one().atomics(), Uint256::one()),
sum_snapshot: Decimal256::zero(),
epoch_snapshot: Uint128::zero(),
scale_snapshot: Uint128::zero(),
},
BidResponse {
idx: Uint128::from(2u128),
collateral_token: "token0000".to_string(),
bidder: "addr0000".to_string(),
amount: Uint256::from(1000u128),
premium_slot: 5u8,
pending_liquidated_collateral: Uint256::zero(),
wait_end: None,
product_snapshot: Decimal256::from_ratio(Decimal256::one().atomics(), Uint256::one()),
sum_snapshot: Decimal256::zero(),
epoch_snapshot: Uint128::zero(),
scale_snapshot: Uint128::zero(),
},
BidResponse {
idx: Uint128::from(3u128),
collateral_token: "token0000".to_string(),
bidder: "addr0000".to_string(),
amount: Uint256::from(1000u128),
premium_slot: 10u8,
pending_liquidated_collateral: Uint256::zero(),
wait_end: None,
product_snapshot: Decimal256::from_ratio(Decimal256::one().atomics(), Uint256::one()),
sum_snapshot: Decimal256::zero(),
epoch_snapshot: Uint128::zero(),
scale_snapshot: Uint128::zero(),
}
]
}
);
let bids_response: BidsResponse = from_json(
&query(
deps.as_ref(),
mock_env(),
QueryMsg::BidsByUser {
collateral_token: "token0000".to_string(),
bidder: "addr0000".to_string(),
start_after: Some(Uint128::from(1u128)),
limit: Some(1u8),
},
)
.unwrap(),
)
.unwrap();
assert_eq!(
bids_response,
BidsResponse {
bids: vec![BidResponse {
idx: Uint128::from(2u128),
collateral_token: "token0000".to_string(),
bidder: "addr0000".to_string(),
amount: Uint256::from(1000u128),
premium_slot: 5u8,
pending_liquidated_collateral: Uint256::zero(),
wait_end: None,
product_snapshot: Decimal256::from_ratio(Decimal256::one().atomics(), Uint256::one()),
sum_snapshot: Decimal256::zero(),
epoch_snapshot: Uint128::zero(),
scale_snapshot: Uint128::zero(),
}]
}
);
}
#[test]
fn query_bid_pools() {
let mut deps = mock_dependencies(&[]);
deps.querier
.with_collateral_max_ltv(&[(&"token0000".to_string(), &Decimal256::percent(90))]);
let msg = InstantiateMsg {
owner: "owner0000".to_string(),
oracle_contract: "oracle0000".to_string(),
stable_contract: "stable0000".to_string(),
safe_ratio: Decimal256::percent(10),
bid_fee: Decimal256::percent(1),
liquidator_fee: Decimal256::percent(0),
liquidation_threshold: Uint256::from(100000000u64),
price_timeframe: 60u64,
waiting_period: 60u64,
overseer: "overseer0000".to_string(),
};
let info = mock_info("addr0000", &[]);
let _res = instantiate(deps.as_mut(), mock_env(), info, msg).unwrap();
let msg = ExecuteMsg::WhitelistCollateral {
collateral_token: "token0000".to_string(),
max_slot: 30u8,
bid_threshold: Uint256::from(10000u128), premium_rate_per_slot: Decimal256::percent(1),
};
let info = mock_info("owner0000", &[]);
execute(deps.as_mut(), mock_env(), info, msg).unwrap();
let info = mock_info("stable0000", &[]);
let msg = ExecuteMsg::Receive(Cw20ReceiveMsg {
sender: "addr0000".to_string(),
amount: Uint128::from(1000u128),
msg: to_json_binary(&Cw20HookMsg::SubmitBid {
collateral_token: "token0000".to_string(),
premium_slot: 5u8,
})
.unwrap(),
});
execute(deps.as_mut(), mock_env(), info.clone(), msg).unwrap();
let msg = ExecuteMsg::Receive(Cw20ReceiveMsg {
sender: "addr0000".to_string(),
amount: Uint128::from(1000u128),
msg: to_json_binary(&Cw20HookMsg::SubmitBid {
collateral_token: "token0000".to_string(),
premium_slot: 6u8,
})
.unwrap(),
});
execute(deps.as_mut(), mock_env(), info.clone(), msg).unwrap();
let msg = ExecuteMsg::Receive(Cw20ReceiveMsg {
sender: "addr0000".to_string(),
amount: Uint128::from(1000u128),
msg: to_json_binary(&Cw20HookMsg::SubmitBid {
collateral_token: "token0000".to_string(),
premium_slot: 10u8,
})
.unwrap(),
});
execute(deps.as_mut(), mock_env(), info, msg).unwrap();
let bid_pool_response: BidPoolResponse = from_json(
&query(
deps.as_ref(),
mock_env(),
QueryMsg::BidPool {
collateral_token: "token0000".to_string(),
bid_slot: 5u8,
},
)
.unwrap(),
)
.unwrap();
assert_eq!(
bid_pool_response,
BidPoolResponse {
total_bid_amount: Uint256::from(1000u128),
premium_rate: Decimal256::percent(5),
sum_snapshot: Decimal256::zero(),
product_snapshot: Decimal256::from_ratio(Decimal256::one().atomics(), Uint256::one()),
current_epoch: Uint128::zero(),
current_scale: Uint128::zero(),
}
);
let bid_pools_response: BidPoolsResponse = from_json(
&query(
deps.as_ref(),
mock_env(),
QueryMsg::BidPoolsByCollateral {
collateral_token: "token0000".to_string(),
start_after: None,
limit: None,
},
)
.unwrap(),
)
.unwrap();
assert_eq!(
bid_pools_response,
BidPoolsResponse {
bid_pools: vec![
BidPoolResponse {
total_bid_amount: Uint256::from(1000u128),
premium_rate: Decimal256::percent(5),
sum_snapshot: Decimal256::zero(),
product_snapshot: Decimal256::from_ratio(Decimal256::one().atomics(), Uint256::one()),
current_epoch: Uint128::zero(),
current_scale: Uint128::zero(),
},
BidPoolResponse {
total_bid_amount: Uint256::from(1000u128),
premium_rate: Decimal256::percent(6),
sum_snapshot: Decimal256::zero(),
product_snapshot: Decimal256::from_ratio(Decimal256::one().atomics(), Uint256::one()),
current_epoch: Uint128::zero(),
current_scale: Uint128::zero(),
},
BidPoolResponse {
total_bid_amount: Uint256::from(1000u128),
premium_rate: Decimal256::percent(10),
sum_snapshot: Decimal256::zero(),
product_snapshot: Decimal256::from_ratio(Decimal256::one().atomics(), Uint256::one()),
current_epoch: Uint128::zero(),
current_scale: Uint128::zero(),
}
]
}
);
let bid_pools_response: BidPoolsResponse = from_json(
&query(
deps.as_ref(),
mock_env(),
QueryMsg::BidPoolsByCollateral {
collateral_token: "token0000".to_string(),
start_after: Some(1u8),
limit: Some(1u8),
},
)
.unwrap(),
)
.unwrap();
assert_eq!(
bid_pools_response,
BidPoolsResponse {
bid_pools: vec![BidPoolResponse {
total_bid_amount: Uint256::from(1000u128),
premium_rate: Decimal256::percent(5),
sum_snapshot: Decimal256::zero(),
product_snapshot: Decimal256::from_ratio(Decimal256::one().atomics(), Uint256::one()),
current_epoch: Uint128::zero(),
current_scale: Uint128::zero(),
},]
}
);
}
#[test]
fn query_collateral_info() {
let mut deps = mock_dependencies(&[]);
deps.querier
.with_collateral_max_ltv(&[(&"token0000".to_string(), &Decimal256::percent(90))]);
let msg = InstantiateMsg {
owner: "owner0000".to_string(),
oracle_contract: "oracle0000".to_string(),
stable_contract: "stable0000".to_string(),
safe_ratio: Decimal256::percent(10),
bid_fee: Decimal256::percent(1),
liquidator_fee: Decimal256::percent(0),
liquidation_threshold: Uint256::from(100000000u64),
price_timeframe: 60u64,
waiting_period: 60u64,
overseer: "overseer0000".to_string(),
};
let info = mock_info("addr0000", &[]);
let _res = instantiate(deps.as_mut(), mock_env(), info, msg).unwrap();
let msg = ExecuteMsg::WhitelistCollateral {
collateral_token: "token0000".to_string(),
max_slot: 30u8,
bid_threshold: Uint256::from(10000u128),
premium_rate_per_slot: Decimal256::percent(1),
};
let info = mock_info("owner0000", &[]);
execute(deps.as_mut(), mock_env(), info, msg).unwrap();
let collateral_info_response: CollateralInfoResponse = from_json(
&query(
deps.as_ref(),
mock_env(),
QueryMsg::CollateralInfo {
collateral_token: "token0000".to_string(),
},
)
.unwrap(),
)
.unwrap();
assert_eq!(
collateral_info_response,
CollateralInfoResponse {
collateral_token: "token0000".to_string(),
max_slot: 30u8,
bid_threshold: Uint256::from(10000u128),
premium_rate_per_slot: Decimal256::percent(1),
}
);
}