From 3e3a75d4c485b87da4767d7e790543b937104f66 Mon Sep 17 00:00:00 2001 From: John Bergschneider Date: Mon, 18 May 2026 17:20:42 -0400 Subject: [PATCH 1/6] Align Distribution balance --- MIPS/MIP-11.md | 43 +++++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/MIPS/MIP-11.md b/MIPS/MIP-11.md index 8dfeb32..cd51cc3 100644 --- a/MIPS/MIP-11.md +++ b/MIPS/MIP-11.md @@ -12,7 +12,7 @@ created: 2026-04-01 ## Abstract -This MIP automatically distributes priority fees to delegators rather than crediting them solely to the validator's beneficiary address. +This MIP automatically distributes priority fees and other transfers accumulated in the distribution account to delegators rather than crediting them solely to the validator's beneficiary address. ## Motivation @@ -26,8 +26,8 @@ To ensure consistent compensation for all stakers without relying on per-validat Automated priority fee distribution has two components: -1. A new account that captures priority fees, referred to as the `distribution account`. The address for the distribution account will be `0xfee5fee5fee5fee5fee5fee5fee5fee5fee5fee5`. -2. End-of-block execution logic that calls `external_rewards` on the corresponding validator pool with the priority fees accumulated in the `distribution account`. +1. A new account that captures priority fees and arbitrary user transfers, referred to as the `distribution account`. The address for the distribution account will be `0xfee5fee5fee5fee5fee5fee5fee5fee5fee5fee5`. +2. End-of-block execution logic that attributes to the corresponding validator pool with the balance accumulated in the `distribution account`. The `beneficiary` remains settable by the block proposer, and within the execution context, `block.coinbase` continues to refer to the beneficiary address. @@ -37,7 +37,7 @@ The following changes are applied during block execution: 1. The beneficiary is still set by the block proposer and is still represented by `block.coinbase` in the execution context. 2. For each transaction, the priority fee is credited to the distribution account rather than to the beneficiary balance. -3. At the end of block execution, the system calls `syscall_distribute` on the distribution account. This function forwards the full accumulated balance to the staking contract via `external_rewards`. +3. At the end of block execution, the system calls `distribute` on the distribution account. This function then forwards the fully accumulated balance to the staking contract if the minimal threshold is meet. The distribution account has the following logic: @@ -46,13 +46,33 @@ class distribution_account: # This function is only callable via execution; no transaction can call it. def syscall_distribute(address block_leader): - priority_fees = get_balance(address(this)) + + # 1. Load Balance and clear balance per block + total_balance = get_balance(address(this)) + set_balance(address(this), 0) - # Same value as the val_id used by syscall_reward for block_leader. + # 2. Same value as the val_id used by syscall_reward for block_leader. val_id = staking_contract.val_id(block_leader) - - # Sub-threshold fees are filtered by external_rewards (see dust_threshold). - staking_contract.external_rewards(val_id){msg.value = priority_fees} + + # 3. Get relevant validator info + val_execution = val_execution(val_id) + val_consensus = val_consensus(val_id) + auth = delegator(val_id,val_execution.auth_address) + + # 4. Get Commission Fee if applicable + commission_amount = 0 + distribute_amount = 0 + if val_consensus.commission_rate > 0: + commission_amount = (total_balance * val_consensus.commission_rate) / 1e18 + + # 5. Check if sufficent to distribute funds + distribute_amount = total_balance - commission_amount + if distribute_amount < DUST_THRESHOLD: + exit + + # 6. Distribute funds + staking_contract.apply_commission_to_auth_account(auth){msg.value = commission_amount} + staking_contract.distribute(val_id){msg.value = distribute_amount} ``` ## Rationale @@ -70,18 +90,17 @@ This change modifies the flow of priority fees: they will no longer appear in th Because priority fees are now distributed to all delegators within a validator's pool, third-party delegation contracts may be affected. Such contracts will experience a dilution in their share of priority fees if users bypass the external contract and stake directly with the validator pool. -To be amenable to this update `external_rewards` will be modified so that it removes the commission fee when called. ## Security Considerations The primary consideration is the precision of the reward accumulator. -`external_rewards` requires a minimum input amount, defined as the `dust_threshold`, in order to guarantee a certain decimal accuracy within the accumulator. The minimum threshold for non-zero priority fees must align with this `external_rewards` minimum-balance requirement, and any fees below this threshold will not be distributed. +In order to guarantee a certain decimal accuracy within the accumulator, the constant `dust_threshold` was defined. The minimum threshold for non-zero priority fees must align with the `dust_threshold` minimum-balance requirement. Any amount below this threshold will not be distributed and will be burned from the supply. Edge cases to consider: 1. Blocks with zero priority fees result in a no-op distribution. -2. Small fee amounts must be validated against `dust_threshold`; sub-threshold fees are burned. +2. Small fee amounts must be validated against `dust_threshold`; Any distributable balance below dust_threshold is burned. ## Copyright From 02151feed94045603a8938d9d83197d1a9ba82e1 Mon Sep 17 00:00:00 2001 From: John Bergschneider Date: Mon, 18 May 2026 17:35:40 -0400 Subject: [PATCH 2/6] Update Mip11 --- MIPS/MIP-11.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MIPS/MIP-11.md b/MIPS/MIP-11.md index cd51cc3..6665f86 100644 --- a/MIPS/MIP-11.md +++ b/MIPS/MIP-11.md @@ -27,7 +27,7 @@ To ensure consistent compensation for all stakers without relying on per-validat Automated priority fee distribution has two components: 1. A new account that captures priority fees and arbitrary user transfers, referred to as the `distribution account`. The address for the distribution account will be `0xfee5fee5fee5fee5fee5fee5fee5fee5fee5fee5`. -2. End-of-block execution logic that attributes to the corresponding validator pool with the balance accumulated in the `distribution account`. +2. End-of-block execution logic that attributes the balance accumulated in the `distribution account` to the corresponding validator pool modulo commission rate. The `beneficiary` remains settable by the block proposer, and within the execution context, `block.coinbase` continues to refer to the beneficiary address. @@ -37,7 +37,7 @@ The following changes are applied during block execution: 1. The beneficiary is still set by the block proposer and is still represented by `block.coinbase` in the execution context. 2. For each transaction, the priority fee is credited to the distribution account rather than to the beneficiary balance. -3. At the end of block execution, the system calls `distribute` on the distribution account. This function then forwards the fully accumulated balance to the staking contract if the minimal threshold is meet. +3. At the end of block execution, the system calls `distribute` on the distribution account. This function then forwards the fully accumulated balance to the staking contract if the minimal threshold is met. The distribution account has the following logic: @@ -95,7 +95,7 @@ Because priority fees are now distributed to all delegators within a validator's The primary consideration is the precision of the reward accumulator. -In order to guarantee a certain decimal accuracy within the accumulator, the constant `dust_threshold` was defined. The minimum threshold for non-zero priority fees must align with the `dust_threshold` minimum-balance requirement. Any amount below this threshold will not be distributed and will be burned from the supply. +The constant `dust_threshold` was defined to guarantee a certain decimal accuracy within the accumulator. The minimum threshold for non-zero priority fees must align with the `dust_threshold` minimum-balance requirement. Any amount below this threshold will not be distributed and will be burned from the supply. Edge cases to consider: From 1bc7f769615ad4a3c8e6364557f941079cfdd46c Mon Sep 17 00:00:00 2001 From: John Bergschneider Date: Mon, 29 Jun 2026 09:31:15 -0700 Subject: [PATCH 3/6] Update MIPS/MIP-11.md Co-authored-by: pdobacz <5735525+pdobacz@users.noreply.github.com> --- MIPS/MIP-11.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MIPS/MIP-11.md b/MIPS/MIP-11.md index 6665f86..d645190 100644 --- a/MIPS/MIP-11.md +++ b/MIPS/MIP-11.md @@ -45,7 +45,7 @@ The distribution account has the following logic: class distribution_account: # This function is only callable via execution; no transaction can call it. - def syscall_distribute(address block_leader): + def distribute(address block_leader): # 1. Load Balance and clear balance per block total_balance = get_balance(address(this)) From d88d8b51fd57c73b58ffa8f2e6391b97f3d9478a Mon Sep 17 00:00:00 2001 From: John Bergschneider Date: Mon, 29 Jun 2026 09:31:24 -0700 Subject: [PATCH 4/6] Update MIPS/MIP-11.md Co-authored-by: pdobacz <5735525+pdobacz@users.noreply.github.com> --- MIPS/MIP-11.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MIPS/MIP-11.md b/MIPS/MIP-11.md index d645190..6765d7f 100644 --- a/MIPS/MIP-11.md +++ b/MIPS/MIP-11.md @@ -57,7 +57,7 @@ class distribution_account: # 3. Get relevant validator info val_execution = val_execution(val_id) val_consensus = val_consensus(val_id) - auth = delegator(val_id,val_execution.auth_address) + auth = delegator(val_id, val_execution.auth_address) # 4. Get Commission Fee if applicable commission_amount = 0 From 28844f8fa3864de4d17685f1537d3b125b3181b4 Mon Sep 17 00:00:00 2001 From: John Bergschneider Date: Tue, 30 Jun 2026 09:58:16 -0400 Subject: [PATCH 5/6] remove initialization --- MIPS/MIP-11.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/MIPS/MIP-11.md b/MIPS/MIP-11.md index 6765d7f..f11c591 100644 --- a/MIPS/MIP-11.md +++ b/MIPS/MIP-11.md @@ -60,8 +60,6 @@ class distribution_account: auth = delegator(val_id, val_execution.auth_address) # 4. Get Commission Fee if applicable - commission_amount = 0 - distribute_amount = 0 if val_consensus.commission_rate > 0: commission_amount = (total_balance * val_consensus.commission_rate) / 1e18 From 4d7c4f14b02682427813dccc6d990313be7de143 Mon Sep 17 00:00:00 2001 From: John Bergschneider Date: Tue, 30 Jun 2026 13:33:08 -0400 Subject: [PATCH 6/6] Update Order of operations --- MIPS/MIP-11.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MIPS/MIP-11.md b/MIPS/MIP-11.md index f11c591..3a16c81 100644 --- a/MIPS/MIP-11.md +++ b/MIPS/MIP-11.md @@ -65,11 +65,12 @@ class distribution_account: # 5. Check if sufficent to distribute funds distribute_amount = total_balance - commission_amount + staking_contract.apply_commission_to_auth_account(auth){msg.value = commission_amount} + if distribute_amount < DUST_THRESHOLD: exit # 6. Distribute funds - staking_contract.apply_commission_to_auth_account(auth){msg.value = commission_amount} staking_contract.distribute(val_id){msg.value = distribute_amount} ```