123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566(*****************************************************************************)(* *)(* SPDX-License-Identifier: MIT *)(* Copyright (c) 2023 Nomadic Labs, <contact@nomadic-labs.com> *)(* *)(*****************************************************************************)typet=Q.ttypemax_bonus=t(* Bonus will represent a fraction of the total supply, so its precision
should be in the order of magnitude of the total supply. *)(* Order of magnitude of the total supply in mutez
Approximately 2^50 *)letbonus_unit=Q.of_int641_000_000_000_000_000Lletzero=Q.zeroletcheck_bounds~max_bonusq=Q.(q>=zero&&q<=max_bonus)[@@inlinealways]typeerror+=Out_of_bounds_bonuslet()=Error_monad.register_error_kind`Permanent~id:"out_of_bound_issuance_bonus"~title:"Out of bound issuance bonus"~description:"Computed issuance bonus is out of bound"~pp:(funppf()->Format.fprintfppf"Computed issuance bonus is out of bound")Data_encoding.unit(functionOut_of_bounds_bonus->Some()|_->None)(fun()->Out_of_bounds_bonus)letof_Q~max_bonusq=letopenResult_syntaxinifcheck_bounds~max_bonusqthenreturnqelsetzfailOut_of_bounds_bonus[@@inlinealways]letof_Q_unboundedq=ifcheck_bounds~max_bonus:Q.oneqthenSomeqelseNoneletof_int64_repri=of_Q_unboundedQ.(div(of_int64i)bonus_unit)letof_int64_repr_erri=letopenResult_syntaxinmatchof_int64_repriwith|Somebonus->returnbonus|None->fail"Issuance bonus must be between 0 and 1"letto_int64_reprq=Q.(mulqbonus_unit|>to_int64)letencoding=Data_encoding.conv_with_guardto_int64_reprof_int64_repr_errData_encoding.int64letmax_bonus_encoding=encodingletmax_bonus_parameter_of_Q_exnq=matchof_Q_unboundedqwith|Somemax_bonus->max_bonus|None->failwith"Invalid parameter: max_bonus parameter must be between 0 and 1"