use bitcoin::Amount;
use ddk_manager::{
contract::{
contract_input::{ContractInput, ContractInputInfo, OracleInput},
numerical_descriptor::NumericalDescriptor,
ContractDescriptor,
},
payout_curve::{
PayoutFunction, PayoutFunctionPiece, PayoutPoint, PolynomialPayoutCurvePiece,
RoundingInterval, RoundingIntervals,
},
};
use ddk_trie::OracleNumericInfo;
pub fn create_parlay_contract(
max_normalized_value: u64,
offer_collateral: Amount,
accept_collateral: Amount,
oracle_input: OracleInput,
fee_rate: u64,
) -> ContractInput {
let payout_function = create_normalized_payout_function(
max_normalized_value,
accept_collateral + offer_collateral,
);
let rounding_intervals = RoundingIntervals {
intervals: vec![
RoundingInterval {
begin_interval: 0,
rounding_mod: 1,
},
RoundingInterval {
begin_interval: 101,
rounding_mod: 10,
},
],
};
let digits_needed = (max_normalized_value as f64).log2().ceil() as u16;
let numerical_descriptor = NumericalDescriptor {
payout_function,
rounding_intervals,
difference_params: None,
oracle_numeric_infos: OracleNumericInfo {
base: 2,
nb_digits: vec![digits_needed as usize],
},
};
let contract_descriptor = ContractDescriptor::Numerical(numerical_descriptor);
let contract_info = ContractInputInfo {
contract_descriptor,
oracles: oracle_input,
};
ContractInput {
offer_collateral,
accept_collateral,
fee_rate,
contract_flags: 0,
contract_infos: vec![contract_info],
}
}
fn create_normalized_payout_function(
max_normalized_value: u64, max_payout: Amount, ) -> PayoutFunction {
let payout_points = vec![
PayoutPoint {
event_outcome: 0,
outcome_payout: Amount::ZERO,
extra_precision: 0,
},
PayoutPoint {
event_outcome: max_normalized_value,
outcome_payout: max_payout,
extra_precision: 0,
},
];
let polynomial_piece = PolynomialPayoutCurvePiece::new(payout_points).unwrap();
let payout_function_piece = PayoutFunctionPiece::PolynomialPayoutCurvePiece(polynomial_piece);
PayoutFunction::new(vec![payout_function_piece]).unwrap()
}