Skip to content

Comments

feat: Treasury config pallet#372

Merged
illuzen merged 2 commits intotestnet/planckfrom
feat/tc_pallet
Feb 17, 2026
Merged

feat: Treasury config pallet#372
illuzen merged 2 commits intotestnet/planckfrom
feat/tc_pallet

Conversation

@czareko
Copy link
Collaborator

@czareko czareko commented Feb 17, 2026

No description provided.

@czareko czareko requested review from illuzen and n13 February 17, 2026 06:55
Copy link
Contributor

@illuzen illuzen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer not to have a 0 address fallback if decoding fails but it shouldn't fail if we have it set so it it's probably fine

@illuzen illuzen merged commit 33c056a into testnet/planck Feb 17, 2026
4 checks passed
@n13
Copy link
Collaborator

n13 commented Feb 17, 2026

postmortem PR review


PR #372 Review: Treasury Config Pallet

Overview

This PR replaces Substrate's full pallet-treasury (with spend proposals, payouts, custom origins, etc.) with a minimal custom config pallet that stores only the treasury account address and mining-reward portion. It also removes the pallet_custom_origins module, 4 treasury governance tracks, and all associated spend tests.


Critical Issues

1. Naming collision: pallet-treasury

The new crate is named pallet-treasury in Cargo.toml, which is the same name as Substrate's pallet-treasury. This completely shadows the upstream crate and will cause confusion for anyone reading the code. Consider naming it pallet-treasury-config or pallet-treasury-params to clearly distinguish it from the well-known Substrate pallet.

2. Pallet index renumbering is a breaking change

All pallet indices from 6 onward are renumbered (e.g., MiningRewards 7->6, Preimage 9->7, etc.). Pallet indices are baked into storage key prefixes. If this testnet has any existing state, this will break all storage reads for the affected pallets. If this is intentional (chain reset), it should be documented. If not, the old indices should be preserved.

3. Overly complex account_id() fallback

pub fn account_id() -> T::AccountId {
    TreasuryAccount::<T>::get().unwrap_or_else(|| {
        T::AccountId::decode(&mut sp_runtime::traits::TrailingZeroInput::zeroes())
            .unwrap_or_else(|_| {
                T::AccountId::decode(&mut &[0u8; 32][..])
                    .unwrap_or_else(|_| panic!("Cannot create fallback AccountId"))
            })
    })
}

This has nested fallbacks with a panic! in the innermost path. Since the genesis config always sets the account, this complexity is unnecessary and the panic path is a liability. Consider either making the storage ValueQuery with a sensible default, or simply panicking immediately if the storage is empty (which indicates a misconfiguration).


Design Concerns

4. u8 portion loses precision vs Permill

Previously TreasuryPortion was a Permill (parts-per-million precision). Now it's a u8 (0-100), which limits precision to whole percentages. The conversion Permill::from_percent(u32::from(treasury_portion)) is then repeated 13+ times across mining-rewards tests — a clear DRY violation. At minimum, the TreasuryProvider trait should return Permill directly, or a helper function should encapsulate the conversion.

5. Massive scope removal without explanation

The PR removes:

  • All treasury spend/payout functionality
  • RuntimeNativePaymaster and RuntimeNativeBalanceConverter
  • pallet_custom_origins (SmallSpender, MediumSpender, BigSpender, Treasurer)
  • 4 treasury governance tracks (tracks 2-5 from community referenda)
  • ~800+ lines of treasury spend tests

The PR description is empty. This is a significant governance capability reduction that deserves a clear rationale — is treasury spending being reimplemented differently? Deferred to a future PR? Permanently removed?

6. No storage migration

Switching from Substrate's pallet-treasury to this custom one changes the storage layout entirely. Existing chains would need a migration to clean up old storage and populate the new TreasuryAccount/TreasuryPortion values.


Minor Issues

7. Unused getter structs

TreasuryAccountGetter<T> and TreasuryPortionGetter<T> are defined but never used anywhere in the PR. If they're for future use, they should be removed until needed (YAGNI).

8. Double #[cfg(test)] gating

In pallets/treasury/src/tests.rs, the entire file is wrapped in #[cfg(test)] mod tests { ... }, but the file is already conditionally compiled via #[cfg(test)] mod tests; in lib.rs. The inner #[cfg(test)] is redundant.

9. set_treasury_account accepts any account

There's no validation that the new treasury account is non-zero or otherwise valid. While root-only access is a reasonable guard, a zero/default account would silently break reward distribution.

10. Bare use pallet_treasury; import

In pallets/mining-rewards/src/mock.rs, the bare use pallet_treasury; may produce an unused-import warning depending on how the compiler resolves it vs the construct_runtime! macro.


What Looks Good

  • The TreasuryProvider trait is a clean abstraction for mining-rewards integration
  • Benchmarks are properly structured with v2 macros
  • Weight file includes actual benchmark data
  • Genesis config with validation (portion <= 100) is solid
  • Root-only access for both setters is appropriate
  • The pallet tests cover the core paths (genesis, setters, authorization, validation)

Summary

The core idea — a lightweight config pallet for treasury account/portion — is sound. However, the PR needs attention on:

  1. Rename the crate to avoid shadowing Substrate's pallet-treasury
  2. Preserve pallet indices or document the chain reset
  3. Simplify the account_id() fallback
  4. Extract the Permill::from_percent(u32::from(...)) pattern into a helper (or return Permill from the trait)
  5. Add PR description explaining why full treasury-spend functionality is being removed
  6. Remove unused TreasuryAccountGetter/TreasuryPortionGetter (or use them)

czareko added a commit that referenced this pull request Feb 17, 2026
* feat: qp-header for Planck release (#338)

* no circuit padding hasher for block header

* *use custom hasher for header that encodes the pre-image in a felt aligned manner.

* *bespoke header hasher

* *patch bug with hash header fall back

* *replace custom poseidon header hasher on
generic header with a fork of header that has a custom
hasher that overrides default on the header trait.

* *rmv commented out impl of prior hash method

* Update primitives/header/src/lib.rs

Co-authored-by: Dastan <88332432+dastansam@users.noreply.github.com>

* fixed tests

* Use inherent struct method

* Update Cargo.toml

---------

Co-authored-by: Ethan <tylercemer@gmail.com>
Co-authored-by: illuzen <illuzen@users.noreply.github.com>
Co-authored-by: Dastan <88332432+dastansam@users.noreply.github.com>

* burn high-security fee instead of sending to treasury (#357)

* Continuous Mining (#358)

* new block trigger

* dedupe logic, remove unnecessary field

* simplify again

* fmt

* clippy

* fmt

* feat: Vesting and MerkleAirdrop removed (#360)

* feat: Merkle Airdrop - removed

* feat: Vesting pallet - removed

* fix: Clippy for header

* Enable wormhole addresses in genesis (#359)

* generate transfer proofs for genesis endowment

* fmt

* fix balances tests

* fmt

* add recover funds call (#361)

* add recover funds call

* add unit tests

* fix up remaining tests

* cargo fmt

* fix benchmarks, update weights

* fix merge error

* feat: Custom Mutisig Pallet  (#352)

* feat: Merkle Airdrop - removed

* feat: Vesting pallet - removed

* poc: First multisig version

* fix: Taplo

* fix: Execution for expired & address simplified fallback

* draft: Historical proposals - paginaged endpoint

* draft: Historical proposals - from events only

* ref: Events renamed + Deposits logic simplified

* feat: GracePeriod param removed

* fix: Reentrancy

* feat: History cleaning redesigned

* fix: Expiry - additional validation

* feat: Proposal nonce

* feat: Dynamic weights

* feat: Multisig deposit fee

* feat: MaxExpiry param

* feat: Fees to Treasury

* feat: History removable only by signers

* fix: Weights

* feat: Fees burned

* feat: Filibuster protection

* feat: Proposals auto cleaning

* feat: Proposal id - nonce instead of hash

* feat: Calls - production whitelist

* feat: Remove call whitelisting

* fix: Test fix after balances pallet update

* fix: Review cleaning

* fix: Multisig - auto-cleaning expanded (#364)

* fix: Multisig - auto-cleaning expanded

* fix: Weights related to storage size

* QUIC miner (#363)

* quic implementation

* refactor for readability

* simplify

* miner initiates, multiple miners supported

* simplify loop further

* short job counters

* simplify new_full

* gracefully handle invalid seals

* remove unused and log misbehaving miners

* emoji

* fmt

* taplo

* improve readability, logs, documentation

* feat: High-Security Integration for Multisig Pallet (#368)

* feat: Multisig + HS integrated

* feat: Weights update

* fix: Benchmarks + README

* feat: HS trait defined in primitives

* fix: Taplo

* fix: Sell order tracking

* feat: Deterministic address + simplified cleaning

* fix: Deposits for multisig

* fix: Dynamic weight + benchmarks refactor

* feat: Execute - separated

* feat: Multisig - benchamarks refactor

* fix: Benchmarks - corrected HS multisig cost

* feat: Dynamic cleaning methods

* feat: Approve dissolve - two variants

* feat: Approval with negative weight

* Switch to new plonky2  (#367)

* No pad hasher header (#327)

* no circuit padding hasher for block header

* *use custom hasher for header that encodes the pre-image in a felt aligned manner.

* *bespoke header hasher

* *patch bug with hash header fall back

* *replace custom poseidon header hasher on
generic header with a fork of header that has a custom
hasher that overrides default on the header trait.

* *rmv commented out impl of prior hash method

* Update primitives/header/src/lib.rs

Co-authored-by: Dastan <88332432+dastansam@users.noreply.github.com>

* fixed tests

* Use inherent struct method

* Update Cargo.toml

---------

Co-authored-by: Ethan <tylercemer@gmail.com>
Co-authored-by: illuzen <illuzen@users.noreply.github.com>

* Verify header in the wormhole proof (#295)

* Use canonical balances pallet and add support for assets in wormhole (#333)

* Use canonical balances pallet, add assets support to wormhole

* Ignore old tests

* Remove tests

* Override native asset id

* Use poseidon hasher

* Use poseidon storage hasher

* Passing wormhole proof tests

* Update binaries

* Update binaries

* Update zk-circuits crates

* Use crates.io dep versions

* Use `ToFelts` trait in the wormhole pallet (#347)

* Apply ToFelts changes to wormhole

* Fix checks

* Passing tests

* Revert unit test line

* Rename explicit AccountId

* Add ValidateUnsigned impl to wormhole (#353)

* feat: aggregated proof verification in wormhole (#351)

* Aggregated proofs verification wormhole

* clippy

* check block hash in agg proof

* feat: quantized funding amounts (#354)

* feat/quantized_wormhole_funding_amount

* *fix formatting

* *rollback zk enabled circuit artfiact builds at runtime.

* fmt

---------

Co-authored-by: illuzen <illuzen@users.noreply.github.com>

* Enforce miner wormhole address (#344)

* feat: qp-header for Planck release (#338)

* no circuit padding hasher for block header

* *use custom hasher for header that encodes the pre-image in a felt aligned manner.

* *bespoke header hasher

* *patch bug with hash header fall back

* *replace custom poseidon header hasher on
generic header with a fork of header that has a custom
hasher that overrides default on the header trait.

* *rmv commented out impl of prior hash method

* Update primitives/header/src/lib.rs

Co-authored-by: Dastan <88332432+dastansam@users.noreply.github.com>

* fixed tests

* Use inherent struct method

* Update Cargo.toml

---------

Co-authored-by: Ethan <tylercemer@gmail.com>
Co-authored-by: illuzen <illuzen@users.noreply.github.com>
Co-authored-by: Dastan <88332432+dastansam@users.noreply.github.com>

* Exponentially decaying token rewards (#340)

* exponentially decaying token rewards

* script to simulate emissions

* clean up constants and switch python script to rust test

* log if we hit max supply somehow

* convert rewards_address to rewards_preimage to enforce wormhole address usage

* better documentation

* change arg name

* Exponentially decaying token rewards (#340)

* exponentially decaying token rewards

* script to simulate emissions

* clean up constants and switch python script to rust test

* log if we hit max supply somehow

* convert rewards_address to rewards_preimage to enforce wormhole address usage

* better documentation

* change arg name

* address style comments

---------

Co-authored-by: Cezary Olborski <cezary.olborski@gmail.com>
Co-authored-by: Ethan <tylercemer@gmail.com>
Co-authored-by: Dastan <88332432+dastansam@users.noreply.github.com>

* update qp-poseidon version

* made transfer count per-recipient

* feat: enable wormhole verifier tests (#356)

* bring back wormhole transfer proof generation tests

* fmt

---------

Co-authored-by: illuzen <illuzen@users.noreply.github.com>

* remove painful test, we sent it to quantus-cli

* burn half the volume fee

* fmt

* use new plonky2-verifier crate

* fix: Remove no_random feature and patch plonky2 crates to use local versions

- Remove no_random feature from qp-wormhole-verifier and qp-zk-circuits-common dependencies
- Add patches to use local qp-plonky2 and qp-plonky2-field with fixed rand feature handling
- These changes ensure consistent feature resolution across all workspace members

* lock

* new agg logic

* better logging of agg proof failure modes

* refresh bins

* only one proof verified event necessary

* update to latest rusty crystals

* no minimum, no single proof verification

* lock

* handle new derivation rules

* fmt

* put wormhole transfer minimum back in, remove unused single-proof files

* better lock

* remove local plonky2 references

* fix build.rs bin validation

* remove unused functions

* format

* no more local deps

* missing dev accounts

* clippy

---------

Co-authored-by: Dastan <88332432+dastansam@users.noreply.github.com>
Co-authored-by: Ethan <tylercemer@gmail.com>
Co-authored-by: Cezary Olborski <cezary.olborski@gmail.com>

* generate TransferProofs on batch transfer

* clippy + zk versions

* feat: Treasury config pallet (#372)

* feat: Treasury config pallet

* fix: Taplo

---------

Co-authored-by: Ethan <tylercemer@gmail.com>
Co-authored-by: illuzen <illuzen@users.noreply.github.com>
Co-authored-by: Dastan <88332432+dastansam@users.noreply.github.com>
Co-authored-by: Nikolaus Heger <nheger@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants