From f623625bb5ce3fa7404e74400ac8865c74e73c41 Mon Sep 17 00:00:00 2001 From: Mehdi Bouaziz Date: Fri, 9 Jun 2023 11:37:07 +0200 Subject: [PATCH 1/5] Proto/Staking_pseudotokens: no pseudotokens if no tez --- .../staking_pseudotokens_storage.ml | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/proto_alpha/lib_protocol/staking_pseudotokens_storage.ml b/src/proto_alpha/lib_protocol/staking_pseudotokens_storage.ml index 7439e943ce1a..2c59ff45c0d5 100644 --- a/src/proto_alpha/lib_protocol/staking_pseudotokens_storage.ml +++ b/src/proto_alpha/lib_protocol/staking_pseudotokens_storage.ml @@ -115,10 +115,19 @@ let frozen_deposits_pseudotokens_for_tez_amount ctxt delegate tez_amount = let* {current_amount = frozen_deposits_tez; initial_amount = _} = Frozen_deposits_storage.get ctxt contract in - let+ frozen_deposits_pseudotokens = - Storage.Contract.Frozen_deposits_pseudotokens.get ctxt contract - in - pseudotokens_of ~frozen_deposits_pseudotokens ~frozen_deposits_tez ~tez_amount + if Tez_repr.(frozen_deposits_tez = zero) then + (* [Frozen_deposits_pseudotokens] may not be initialized when there are no + frozen deposits tez. This may happen when a new delegate is registered. *) + return + Staking_pseudotoken_repr.(of_int64_exn (Tez_repr.to_mutez tez_amount)) + else + let+ frozen_deposits_pseudotokens = + Storage.Contract.Frozen_deposits_pseudotokens.get ctxt contract + in + pseudotokens_of + ~frozen_deposits_pseudotokens + ~frozen_deposits_tez + ~tez_amount let update_frozen_deposits_pseudotokens ~f ctxt delegate = let open Lwt_result_syntax in -- GitLab From 9deb890fed8f9777fa6753324e5e36fb42f81d94 Mon Sep 17 00:00:00 2001 From: Mehdi Bouaziz Date: Fri, 9 Jun 2023 11:43:21 +0200 Subject: [PATCH 2/5] Proto/Staking_pseudotokens: avoid division by zero --- .../staking_pseudotokens_storage.ml | 36 +++++++++++-------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/proto_alpha/lib_protocol/staking_pseudotokens_storage.ml b/src/proto_alpha/lib_protocol/staking_pseudotokens_storage.ml index 2c59ff45c0d5..452f5e9b80ea 100644 --- a/src/proto_alpha/lib_protocol/staking_pseudotokens_storage.ml +++ b/src/proto_alpha/lib_protocol/staking_pseudotokens_storage.ml @@ -93,21 +93,27 @@ let pseudotokens_of ~frozen_deposits_pseudotokens ~frozen_deposits_tez let tez_of ~frozen_deposits_pseudotokens ~frozen_deposits_tez ~pseudotoken_amount = - let frozen_deposits_tez_z = - Z.of_int64 (Tez_repr.to_mutez frozen_deposits_tez) - in - let frozen_deposits_pseudotokens_z = - Z.of_int64 (Staking_pseudotoken_repr.to_int64 frozen_deposits_pseudotokens) - in - let pseudotoken_amount_z = - Z.of_int64 (Staking_pseudotoken_repr.to_int64 pseudotoken_amount) - in - let res_z = - Z.div - (Z.mul frozen_deposits_tez_z pseudotoken_amount_z) - frozen_deposits_pseudotokens_z - in - Tez_repr.of_mutez_exn (Z.to_int64 res_z) + if Staking_pseudotoken_repr.(frozen_deposits_pseudotokens = zero) then ( + (* When there are no frozen deposits, starts with 1 mutez = 1 pseudotoken. *) + assert (Tez_repr.(frozen_deposits_tez = zero)) ; + Tez_repr.of_mutez_exn (Staking_pseudotoken_repr.to_int64 pseudotoken_amount)) + else + let frozen_deposits_tez_z = + Z.of_int64 (Tez_repr.to_mutez frozen_deposits_tez) + in + let frozen_deposits_pseudotokens_z = + Z.of_int64 + (Staking_pseudotoken_repr.to_int64 frozen_deposits_pseudotokens) + in + let pseudotoken_amount_z = + Z.of_int64 (Staking_pseudotoken_repr.to_int64 pseudotoken_amount) + in + let res_z = + Z.div + (Z.mul frozen_deposits_tez_z pseudotoken_amount_z) + frozen_deposits_pseudotokens_z + in + Tez_repr.of_mutez_exn (Z.to_int64 res_z) let frozen_deposits_pseudotokens_for_tez_amount ctxt delegate tez_amount = let open Lwt_result_syntax in -- GitLab From 43367d3c4ba4e94f514b27dd98ed8334ef24b78f Mon Sep 17 00:00:00 2001 From: Mehdi Bouaziz Date: Fri, 9 Jun 2023 11:45:49 +0200 Subject: [PATCH 3/5] Proto/Staking_pseudotokens: ignore zero-amount transfers --- .../staking_pseudotokens_storage.ml | 62 ++++++++++--------- 1 file changed, 34 insertions(+), 28 deletions(-) diff --git a/src/proto_alpha/lib_protocol/staking_pseudotokens_storage.ml b/src/proto_alpha/lib_protocol/staking_pseudotokens_storage.ml index 452f5e9b80ea..20ecf2b68043 100644 --- a/src/proto_alpha/lib_protocol/staking_pseudotokens_storage.ml +++ b/src/proto_alpha/lib_protocol/staking_pseudotokens_storage.ml @@ -157,38 +157,44 @@ let update_frozen_deposits_pseudotokens ~f ctxt delegate = let credit_frozen_deposits_pseudotokens_for_tez_amount ctxt delegate tez_amount = - let f ~frozen_deposits_pseudotokens ~frozen_deposits_tez = - let open Result_syntax in - let pseudotokens_to_add = - pseudotokens_of - ~frozen_deposits_pseudotokens - ~frozen_deposits_tez - ~tez_amount - in - let+ new_pseudotokens_balance = - Staking_pseudotoken_repr.( - pseudotokens_to_add +? frozen_deposits_pseudotokens) + if Tez_repr.(tez_amount = zero) then + return (ctxt, Staking_pseudotoken_repr.zero) + else + let f ~frozen_deposits_pseudotokens ~frozen_deposits_tez = + let open Result_syntax in + let pseudotokens_to_add = + pseudotokens_of + ~frozen_deposits_pseudotokens + ~frozen_deposits_tez + ~tez_amount + in + let+ new_pseudotokens_balance = + Staking_pseudotoken_repr.( + pseudotokens_to_add +? frozen_deposits_pseudotokens) + in + (new_pseudotokens_balance, pseudotokens_to_add) in - (new_pseudotokens_balance, pseudotokens_to_add) - in - update_frozen_deposits_pseudotokens ~f ctxt delegate + update_frozen_deposits_pseudotokens ~f ctxt delegate let debit_frozen_deposits_pseudotokens ctxt delegate pseudotoken_amount = - let f ~frozen_deposits_pseudotokens ~frozen_deposits_tez = - let open Result_syntax in - let+ new_pseudotokens_balance = - Staking_pseudotoken_repr.( - frozen_deposits_pseudotokens -? pseudotoken_amount) - in - let tez_amount = - tez_of - ~frozen_deposits_pseudotokens - ~frozen_deposits_tez - ~pseudotoken_amount + if Staking_pseudotoken_repr.(pseudotoken_amount = zero) then + return (ctxt, Tez_repr.zero) + else + let f ~frozen_deposits_pseudotokens ~frozen_deposits_tez = + let open Result_syntax in + let+ new_pseudotokens_balance = + Staking_pseudotoken_repr.( + frozen_deposits_pseudotokens -? pseudotoken_amount) + in + let tez_amount = + tez_of + ~frozen_deposits_pseudotokens + ~frozen_deposits_tez + ~pseudotoken_amount + in + (new_pseudotokens_balance, tez_amount) in - (new_pseudotokens_balance, tez_amount) - in - update_frozen_deposits_pseudotokens ~f ctxt delegate + update_frozen_deposits_pseudotokens ~f ctxt delegate let costaking_pseudotokens_balance ctxt contract = let open Lwt_result_syntax in -- GitLab From 2709a9ce1e110437dbffa2eaa43065cbbaa8111d Mon Sep 17 00:00:00 2001 From: Mehdi Bouaziz Date: Fri, 9 Jun 2023 11:49:20 +0200 Subject: [PATCH 4/5] Proto/Staking: split request_unstake --- src/proto_alpha/lib_protocol/staking.ml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/proto_alpha/lib_protocol/staking.ml b/src/proto_alpha/lib_protocol/staking.ml index 11d901fa0ed2..155cb4604979 100644 --- a/src/proto_alpha/lib_protocol/staking.ml +++ b/src/proto_alpha/lib_protocol/staking.ml @@ -143,9 +143,8 @@ let stake ctxt ~sender ~delegate amount = in return (ctxt, stake_balance_updates @ finalize_balance_updates) -let request_unstake ctxt ~sender_contract ~delegate requested_amount = +let record_request_unstake ctxt ~sender_contract ~delegate requested_amount = let open Lwt_result_syntax in - let* ctxt, finalize_balance_updates = finalize_unstake ctxt sender_contract in let* requested_pseudotokens = Staking_pseudotokens.frozen_deposits_pseudotokens_for_tez_amount ctxt @@ -171,7 +170,7 @@ let request_unstake ctxt ~sender_contract ~delegate requested_amount = pseudotokens_to_unstake in let current_cycle = (Level.current ctxt).cycle in - let* ctxt, unstake_balance_updates = + let* ctxt, balance_updates = Token.transfer ctxt (`Frozen_deposits delegate) @@ -186,4 +185,12 @@ let request_unstake ctxt ~sender_contract ~delegate requested_amount = current_cycle tez_to_unstake in + (ctxt, balance_updates) + +let request_unstake ctxt ~sender_contract ~delegate requested_amount = + let open Lwt_result_syntax in + let* ctxt, finalize_balance_updates = finalize_unstake ctxt sender_contract in + let+ ctxt, unstake_balance_updates = + record_request_unstake ctxt ~sender_contract ~delegate requested_amount + in (ctxt, unstake_balance_updates @ finalize_balance_updates) -- GitLab From 138a0d6f644754648f7112d0cf975b4f4a68361c Mon Sep 17 00:00:00 2001 From: Mehdi Bouaziz Date: Fri, 9 Jun 2023 11:51:20 +0200 Subject: [PATCH 5/5] Proto/Staking: shortcut zero-amount requests --- .../lib_protocol/alpha_context.mli | 4 + src/proto_alpha/lib_protocol/staking.ml | 87 ++++++++++--------- 2 files changed, 50 insertions(+), 41 deletions(-) diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index 6fcfd1635a1c..f1944074c462 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -4914,8 +4914,12 @@ end module Staking_pseudotokens : sig type t + val zero : t + val min : t -> t -> t + val ( = ) : t -> t -> bool + val frozen_deposits_pseudotokens_for_tez_amount : context -> public_key_hash -> Tez.t -> t tzresult Lwt.t diff --git a/src/proto_alpha/lib_protocol/staking.ml b/src/proto_alpha/lib_protocol/staking.ml index 155cb4604979..b3cc7e1a0bbe 100644 --- a/src/proto_alpha/lib_protocol/staking.ml +++ b/src/proto_alpha/lib_protocol/staking.ml @@ -145,47 +145,52 @@ let stake ctxt ~sender ~delegate amount = let record_request_unstake ctxt ~sender_contract ~delegate requested_amount = let open Lwt_result_syntax in - let* requested_pseudotokens = - Staking_pseudotokens.frozen_deposits_pseudotokens_for_tez_amount - ctxt - delegate - requested_amount - in - let* available_pseudotokens = - Staking_pseudotokens.costaking_pseudotokens_balance ctxt sender_contract - in - let pseudotokens_to_unstake = - Staking_pseudotokens.min requested_pseudotokens available_pseudotokens - in - let* ctxt, tez_to_unstake = - Staking_pseudotokens.debit_frozen_deposits_pseudotokens - ctxt - delegate - pseudotokens_to_unstake - in - let* ctxt = - Staking_pseudotokens.debit_costaking_pseudotokens - ctxt - sender_contract - pseudotokens_to_unstake - in - let current_cycle = (Level.current ctxt).cycle in - let* ctxt, balance_updates = - Token.transfer - ctxt - (`Frozen_deposits delegate) - (`Unstaked_frozen_deposits (delegate, current_cycle)) - tez_to_unstake - in - let+ ctxt = - Unstake_requests.add - ctxt - ~contract:sender_contract - ~delegate - current_cycle - tez_to_unstake - in - (ctxt, balance_updates) + if Tez.(requested_amount = zero) then return (ctxt, []) + else + let* requested_pseudotokens = + Staking_pseudotokens.frozen_deposits_pseudotokens_for_tez_amount + ctxt + delegate + requested_amount + in + let* available_pseudotokens = + Staking_pseudotokens.costaking_pseudotokens_balance ctxt sender_contract + in + let pseudotokens_to_unstake = + Staking_pseudotokens.min requested_pseudotokens available_pseudotokens + in + if Staking_pseudotokens.(pseudotokens_to_unstake = zero) then + return (ctxt, []) + else + let* ctxt, tez_to_unstake = + Staking_pseudotokens.debit_frozen_deposits_pseudotokens + ctxt + delegate + pseudotokens_to_unstake + in + let* ctxt = + Staking_pseudotokens.debit_costaking_pseudotokens + ctxt + sender_contract + pseudotokens_to_unstake + in + let current_cycle = (Level.current ctxt).cycle in + let* ctxt, balance_updates = + Token.transfer + ctxt + (`Frozen_deposits delegate) + (`Unstaked_frozen_deposits (delegate, current_cycle)) + tez_to_unstake + in + let+ ctxt = + Unstake_requests.add + ctxt + ~contract:sender_contract + ~delegate + current_cycle + tez_to_unstake + in + (ctxt, balance_updates) let request_unstake ctxt ~sender_contract ~delegate requested_amount = let open Lwt_result_syntax in -- GitLab