fix(emission): integrity_test guard — shares autor+treasury ≤ 100% (audit ultra)
Hallazgo MEDIUM del audit ultra: si un cambio de config hiciera AuthorShareBps + TreasuryShareBps > 10_000 bps, el `subsidy = reward.saturating_sub(author). saturating_sub(treasury)` daría subsidy = 0 SILENCIOSAMENTE (el pool #16 se quedaría sin fondos sin ruido). El hook `integrity_test()` lo convierte en un fallo ruidoso del integrity-check del runtime. +test. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
1fdc47e859
commit
d6dd08da66
1 file changed
+24
-2
@@ -180,9 +180,23 @@ pub mod pallet {
|
||||
|
||||
#[pallet::hooks]
|
||||
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
|
||||
/// Guard de integridad (audit ultra 2026-07-02): las shares autor +
|
||||
/// treasury JAMÁS pueden exceder 100% — el residual es el subsidy pool
|
||||
/// (`subsidy = reward − author − treasury`). Si un futuro cambio de
|
||||
/// config las hiciera sumar > 10_000 bps, el `saturating_sub` daría
|
||||
/// subsidy = 0 SILENCIOSAMENTE. Esto lo convierte en un fallo ruidoso
|
||||
/// en el build/integrity-check del runtime.
|
||||
fn integrity_test() {
|
||||
assert!(
|
||||
T::AuthorShareBps::get().saturating_add(T::TreasuryShareBps::get()) <= 10_000,
|
||||
"emisión: AuthorShareBps + TreasuryShareBps no pueden exceder 100% \
|
||||
(el residual es el subsidy pool #16)"
|
||||
);
|
||||
}
|
||||
|
||||
/// Cada bloque: identifica al autor Aura (desde los pre-runtime digests),
|
||||
/// mintea el BlockReward y lo reparte. Si no hay autor (e.g. bloque de
|
||||
/// inherentes sin pre-digest), no mintea.
|
||||
/// libera el BlockReward del pool Ecosystem y lo reparte. Si no hay autor
|
||||
/// (e.g. bloque de inherentes sin pre-digest), no libera.
|
||||
fn on_initialize(_n: BlockNumberFor<T>) -> Weight {
|
||||
// Kill-switch (governance): si la emisión está pausada, no libera nada.
|
||||
// Lee 1 storage value; default `false` ⇒ activa (cero regresión).
|
||||
@@ -496,6 +510,14 @@ mod tests {
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn integrity_test_shares_no_exceden_100pct() {
|
||||
new_test_ext().execute_with(|| {
|
||||
// Mock: 7000 + 2000 = 9000 ≤ 10000 ⇒ pasa (el residual 1000 = subsidy).
|
||||
<Emission as Hooks<u64>>::integrity_test();
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn depletion_event_se_anuncia_una_sola_vez() {
|
||||
new_test_ext_with_pool(500).execute_with(|| {
|
||||
|
||||
Reference in new issue
Block a user