1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
use super::*;
use std::sync::Arc;
pub struct Put<'a> {
amount: Amount,
strike_x_one_unit: u64,
operator_api: &'a dyn apis::OperatorApi,
user_api: &'a dyn apis::UserApi,
symbol: Symbol,
buying: bool,
ctx: Context,
}
const ONE_UNIT: u64 = 10_000;
impl<'a> TryFrom<Put<'a>> for GenericBetArguments<'a> {
type Error = CompilationError;
fn try_from(mut v: Put<'a>) -> Result<Self, Self::Error> {
let key = v.operator_api.get_key();
let user = v.user_api.get_key();
let mut outcomes = vec![];
let strike = v.strike_x_one_unit;
let max_amount_bitcoin = v.amount * strike;
let mut strike_ctx = v.ctx.derive_str(Arc::new("strike".into()))?;
for price in (0..=strike).step_by(ONE_UNIT as usize) {
let mut profit = Amount::from_sat(strike) - Amount::from_sat(price);
let mut refund = max_amount_bitcoin - profit;
if v.buying {
std::mem::swap(&mut profit, &mut refund);
}
outcomes.push((
price as i64,
strike_ctx
.derive_num(price as u64)?
.template()
.add_output(profit, &v.user_api.receive_payment(profit), None)?
.add_output(refund, &v.operator_api.receive_payment(refund), None)?
.into(),
));
}
Ok(GenericBetArguments {
amount: max_amount_bitcoin,
outcomes,
oracle: v.operator_api.get_oracle(),
cooperate: Clause::And(vec![key, user]),
symbol: v.symbol,
})
}
}
impl<'a> TryFrom<Put<'a>> for GenericBet {
type Error = CompilationError;
fn try_from(v: Put<'a>) -> Result<Self, Self::Error> {
Ok(GenericBetArguments::try_from(v)?.into())
}
}