From ce9226861c353645f377e289ad088d7846d5fa64 Mon Sep 17 00:00:00 2001 From: Lucas Randazzo Date: Mon, 11 Mar 2024 15:51:37 +0100 Subject: [PATCH] Proto/tests: fix slashing roundings --- .../test/helpers/slashing_helpers.ml | 51 +++--------------- .../test/helpers/tez_staking_helpers.ml | 53 ++++++++++++++----- 2 files changed, 47 insertions(+), 57 deletions(-) diff --git a/src/proto_alpha/lib_protocol/test/helpers/slashing_helpers.ml b/src/proto_alpha/lib_protocol/test/helpers/slashing_helpers.ml index 52fbe46f7ef3..31b0ee322a49 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/slashing_helpers.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/slashing_helpers.ml @@ -154,55 +154,27 @@ let apply_slashing_account all_denunciations_to_apply state misbehaviour in - let get_total_supply acc_map = - String.Map.fold - (fun _name - { - State_account.pkh = _; - contract = _; - delegate = _; - parameters = _; - liquid; - bonds; - frozen_deposits; - unstaked_frozen; - unstaked_finalizable; - staking_delegator_numerator = _; - staking_delegate_denominator = _; - frozen_rights = _; - slashed_cycles = _; - } - tot -> - Tez.( - liquid +! bonds - +! Frozen_tez.total_current frozen_deposits - +! Unstaked_frozen.sum_current unstaked_frozen - +! Unstaked_finalizable.total unstaked_finalizable - +! tot)) - acc_map - Tez.zero - in - let total_before_slash = get_total_supply account_map in let slash_culprit ({frozen_deposits; unstaked_frozen; frozen_rights; _} as acc) = let base_rights = CycleMap.find slashed_cycle frozen_rights |> Option.value ~default:Tez.zero in - let frozen_deposits, slashed_frozen = - Frozen_tez.slash base_rights slashed_pct frozen_deposits + let frozen_deposits, burnt_frozen, rewarded_frozen = + Frozen_tez.slash state.constants base_rights slashed_pct frozen_deposits in let slashed_pct_q = Protocol.Percentage.to_q slashed_pct in let slashed_pct = Q.(100 // 1 * slashed_pct_q |> to_int) in let unstaked_frozen, slashed_unstaked = Unstaked_frozen.slash + state.constants ~slashable_deposits_period:constants.consensus_rights_delay slashed_cycle slashed_pct unstaked_frozen in ( {acc with frozen_deposits; unstaked_frozen}, - slashed_frozen :: slashed_unstaked ) + (burnt_frozen, rewarded_frozen) :: slashed_unstaked ) in let culprit_account = String.Map.find culprit_name account_map @@ -216,25 +188,18 @@ let apply_slashing_account all_denunciations_to_apply culprit_name account_map in - let total_after_slash = get_total_supply account_map in - let portion_reward = - constants.adaptive_issuance.global_limit_of_staking_over_baking + 2 - in (* For each container slashed, the snitch gets a reward transferred. It gets rounded down each time *) let reward_to_snitch = - List.map - (fun x -> Tez.mul_q x Q.(1 // portion_reward) |> Tez.of_q ~round:`Down) - total_slashed - |> List.fold_left Tez.( +! ) Tez.zero + List.map snd total_slashed |> List.fold_left Tez.( +! ) Tez.zero in let account_map = add_liquid_rewards reward_to_snitch rewarded_name account_map in - let actual_total_burnt_amount = - Tez.(total_before_slash -! total_after_slash -! reward_to_snitch) + let total_burnt_amount = + List.map fst total_slashed |> List.fold_left Tez.( +! ) Tez.zero in - return (account_map, actual_total_burnt_amount) + return (account_map, total_burnt_amount) let apply_slashing_state all_denunciations_to_apply ( culprit, diff --git a/src/proto_alpha/lib_protocol/test/helpers/tez_staking_helpers.ml b/src/proto_alpha/lib_protocol/test/helpers/tez_staking_helpers.ml index ebc9b655d8a6..5be0ceb470cf 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/tez_staking_helpers.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/tez_staking_helpers.ml @@ -141,7 +141,7 @@ module Frozen_tez = struct (* For slashing, slash equally *) let sub_tez_from_all_current tez a = let self_portion = Tez.ratio a.self_current (total_current a) in - let self_quantity = Tez.mul_q tez self_portion |> Tez.of_q ~round:`Down in + let self_quantity = Tez.mul_q tez self_portion |> Tez.of_q ~round:`Up in let self_current = if Tez.(self_quantity >= a.self_current) then Tez.zero else Tez.(a.self_current -! self_quantity) @@ -227,12 +227,24 @@ module Frozen_tez = struct let a, amount = sub_current amount account a in ({a with initial = Tez.(a.initial -! amount)}, amount) - let slash base_amount (pct : Protocol.Percentage.t) a = + let slash cst base_amount (pct : Protocol.Percentage.t) a = let pct_q = Protocol.Percentage.to_q pct in - let slashed_amount = Tez.mul_q base_amount pct_q |> Tez.of_q ~round:`Down in let total_current = total_current a in - let slashed_amount_final = Tez.min slashed_amount total_current in - (sub_tez_from_all_current slashed_amount a, slashed_amount_final) + let slashed_amount = + Tez.mul_q base_amount pct_q + |> Tez.of_q ~round:`Down |> Tez.min total_current + in + let rat = + cst.Protocol.Alpha_context.Constants.Parametric.adaptive_issuance + .global_limit_of_staking_over_baking + 2 + in + let rewarded_amount = + Tez.mul_q slashed_amount Q.(1 // rat) |> Tez.of_q ~round:`Down + in + let burnt_amount = Tez.(slashed_amount -! rewarded_amount) in + let a = sub_tez_from_all_current burnt_amount a in + let a = sub_tez_from_all_current rewarded_amount a in + (a, burnt_amount, rewarded_amount) end (** Representation of Unstaked frozen deposits *) @@ -277,11 +289,25 @@ module Unstaked_frozen = struct in Tez.(amount -! slashed_amount) - let apply_slash_to_current slash_pct initial current = + let apply_slash_to_current cst slash_pct initial current = let slashed_amount = - Tez.mul_q initial Q.(slash_pct // 100) |> Tez.of_q ~round:`Down + Tez.mul_q initial Q.(slash_pct // 100) + |> Tez.of_q ~round:`Down |> Tez.min current + in + let rat = + cst.Protocol.Alpha_context.Constants.Parametric.adaptive_issuance + .global_limit_of_staking_over_baking + 2 + in + let rewarded_amount = + Tez.mul_q slashed_amount Q.(1 // rat) |> Tez.of_q ~round:`Down + in + let burnt_amount = Tez.(slashed_amount -! rewarded_amount) in + let actual_slashed_amount = Tez.(rewarded_amount +! burnt_amount) in + let remaining = + Tez.sub_opt current actual_slashed_amount + |> Option.value ~default:Tez.zero in - Tez.sub_opt current slashed_amount |> Option.value ~default:Tez.zero + (remaining, burnt_amount, rewarded_amount) let remove_zeros (a : t) : t = List.filter (fun ({current; _} : r) -> Tez.(current > zero)) a @@ -372,7 +398,7 @@ module Unstaked_frozen = struct let info, rest = pop_cycle cycle t in (info, h :: rest) - let slash ~slashable_deposits_period slashed_cycle pct_times_100 a = + let slash cst ~slashable_deposits_period slashed_cycle pct_times_100 a = remove_zeros a |> List.map (fun @@ -383,14 +409,13 @@ module Unstaked_frozen = struct Cycle.( cycle > slashed_cycle || add cycle slashable_deposits_period < slashed_cycle) - then (r, Tez.zero) + then (r, (Tez.zero, Tez.zero)) else - let new_current = - apply_slash_to_current pct_times_100 initial current + let new_current, burnt, rewarded = + apply_slash_to_current cst pct_times_100 initial current in - let slashed = Tez.(current -! new_current) in let slash_pct = min 100 (pct_times_100 + old_slash_pct) in - ({r with slash_pct; current = new_current}, slashed)) + ({r with slash_pct; current = new_current}, (burnt, rewarded))) |> List.split end -- GitLab