Source file delegate_slashed_deposits_storage.ml
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
let already_slashed_for_double_endorsing ctxt delegate (level : Level_repr.t) =
Storage.Slashed_deposits.find (ctxt, level.cycle) (level.level, delegate)
>>=? function
| None -> return_false
| Some slashed -> return slashed.for_double_endorsing
let already_slashed_for_double_baking ctxt delegate (level : Level_repr.t) =
Storage.Slashed_deposits.find (ctxt, level.cycle) (level.level, delegate)
>>=? function
| None -> return_false
| Some slashed -> return slashed.for_double_baking
let punish_double_endorsing ctxt delegate (level : Level_repr.t) =
let open Lwt_result_syntax in
let* slashed =
Storage.Slashed_deposits.find (ctxt, level.cycle) (level.level, delegate)
in
let updated_slashed =
match slashed with
| None -> {Storage.for_double_endorsing = true; for_double_baking = false}
| Some slashed ->
assert (Compare.Bool.(slashed.for_double_endorsing = false)) ;
{slashed with for_double_endorsing = true}
in
let delegate_contract = Contract_repr.Implicit delegate in
let* frozen_deposits = Frozen_deposits_storage.get ctxt delegate_contract in
let slashing_ratio : Ratio_repr.t =
Constants_storage.ratio_of_frozen_deposits_slashed_per_double_endorsement
ctxt
in
let punish_value =
Tez_repr.(
div_exn
(mul_exn frozen_deposits.initial_amount slashing_ratio.numerator)
slashing_ratio.denominator)
in
let amount_to_burn =
Tez_repr.(min frozen_deposits.current_amount punish_value)
in
let* ctxt, balance_updates =
Token.transfer
ctxt
(`Frozen_deposits delegate)
`Double_signing_punishments
amount_to_burn
in
let* ctxt = Stake_storage.remove_stake ctxt delegate amount_to_burn in
let*! ctxt =
Storage.Slashed_deposits.add
(ctxt, level.cycle)
(level.level, delegate)
updated_slashed
in
return (ctxt, amount_to_burn, balance_updates)
let punish_double_baking ctxt delegate (level : Level_repr.t) =
let open Lwt_result_syntax in
let* slashed =
Storage.Slashed_deposits.find (ctxt, level.cycle) (level.level, delegate)
in
let updated_slashed =
match slashed with
| None -> {Storage.for_double_baking = true; for_double_endorsing = false}
| Some slashed ->
assert (Compare.Bool.(slashed.for_double_baking = false)) ;
{slashed with for_double_baking = true}
in
let delegate_contract = Contract_repr.Implicit delegate in
let* frozen_deposits = Frozen_deposits_storage.get ctxt delegate_contract in
let slashing_for_one_block =
Constants_storage.double_baking_punishment ctxt
in
let amount_to_burn =
Tez_repr.(min frozen_deposits.current_amount slashing_for_one_block)
in
let* ctxt, balance_updates =
Token.transfer
ctxt
(`Frozen_deposits delegate)
`Double_signing_punishments
amount_to_burn
in
let* ctxt = Stake_storage.remove_stake ctxt delegate amount_to_burn in
let*! ctxt =
Storage.Slashed_deposits.add
(ctxt, level.cycle)
(level.level, delegate)
updated_slashed
in
return (ctxt, amount_to_burn, balance_updates)
let clear_outdated_slashed_deposits ctxt ~new_cycle =
let max_slashable_period = Constants_storage.max_slashing_period ctxt in
match Cycle_repr.(sub new_cycle max_slashable_period) with
| None -> Lwt.return ctxt
| Some outdated_cycle -> Storage.Slashed_deposits.clear (ctxt, outdated_cycle)