From dbebf539e6ae2c796fb1026be0740fdeec247f85 Mon Sep 17 00:00:00 2001 From: Josep M Sobrepere <jm.sobrepere@gmail.com> Date: Thu, 20 Mar 2025 12:05:52 +0100 Subject: [PATCH] Treasury: update expire date on payout (#7958) (#7959) Closes #7958 Resets the `payout.expire_at` field with the `PayoutPeriod` every time that there is a valid Payout attempt. --------- Co-authored-by: Victor Oliva <olivarra1@gmail.com> --- prdoc/pr_7959.prdoc | 10 +++++++++ substrate/frame/treasury/src/lib.rs | 1 + substrate/frame/treasury/src/tests.rs | 29 +++++++++++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 prdoc/pr_7959.prdoc diff --git a/prdoc/pr_7959.prdoc b/prdoc/pr_7959.prdoc new file mode 100644 index 00000000000..29e14083588 --- /dev/null +++ b/prdoc/pr_7959.prdoc @@ -0,0 +1,10 @@ +title: Update expire date on treasury payout +doc: +- audience: Runtime Dev + description: |- + Resets the `payout.expire_at` field with the `PayoutPeriod` every time that there is a valid Payout attempt. + Prior to this change, when a spend is approved, it receives an expiry date so that if it’s never claimed, it automatically expires. This makes sense under normal circumstances. However, if someone attempts to claim a valid payout and there isn’t sufficient liquidity to fulfill it, the expiry date currently remains unchanged. This effectively penalizes the claimant in the same way as if they had never requested the payout in the first place. + With this change users are not penalized for liquidity shortages and have a fair window to claim once the funds are available. +crates: +- name: pallet-treasury + bump: patch diff --git a/substrate/frame/treasury/src/lib.rs b/substrate/frame/treasury/src/lib.rs index 2a4f49fd5b3..9d89c80f794 100644 --- a/substrate/frame/treasury/src/lib.rs +++ b/substrate/frame/treasury/src/lib.rs @@ -743,6 +743,7 @@ pub mod pallet { .map_err(|_| Error::<T, I>::PayoutError)?; spend.status = PaymentState::Attempted { id }; + spend.expire_at = now.saturating_add(T::PayoutPeriod::get()); Spends::<T, I>::insert(index, spend); Self::deposit_event(Event::<T, I>::Paid { index, payment_id: id }); diff --git a/substrate/frame/treasury/src/tests.rs b/substrate/frame/treasury/src/tests.rs index 2c2ceac5862..22322c3c5f7 100644 --- a/substrate/frame/treasury/src/tests.rs +++ b/substrate/frame/treasury/src/tests.rs @@ -669,6 +669,35 @@ fn spend_payout_works() { }); } +#[test] +fn payout_extends_expiry() { + ExtBuilder::default().build().execute_with(|| { + assert_eq!(<Test as Config>::PayoutPeriod::get(), 5); + + System::set_block_number(1); + assert_ok!(Treasury::spend(RuntimeOrigin::signed(10), Box::new(1), 2, Box::new(6), None)); + // Fail a payout at block 4 + System::set_block_number(4); + assert_ok!(Treasury::payout(RuntimeOrigin::signed(1), 0)); + assert_eq!(paid(6, 1), 2); + let payment_id = get_payment_id(0).expect("no payment attempt"); + // spend payment is failed + set_status(payment_id, PaymentStatus::Failure); + unpay(6, 1, 2); + + // check status to set the correct state + assert_ok!(Treasury::check_status(RuntimeOrigin::signed(1), 0)); + System::assert_last_event(Event::<Test, _>::PaymentFailed { index: 0, payment_id }.into()); + + // Retrying at after the initial expiry date but before the new one succeeds + System::set_block_number(7); + + // the payout can be retried now + assert_ok!(Treasury::payout(RuntimeOrigin::signed(1), 0)); + assert_eq!(paid(6, 1), 2); + }); +} + #[test] fn payout_retry_works() { ExtBuilder::default().build().execute_with(|| { -- GitLab