diff --git a/aptos-move/aptos-release-builder/src/components/feature_flags.rs b/aptos-move/aptos-release-builder/src/components/feature_flags.rs index 755f964346a3b4..96cddb01cdb97b 100644 --- a/aptos-move/aptos-release-builder/src/components/feature_flags.rs +++ b/aptos-move/aptos-release-builder/src/components/feature_flags.rs @@ -211,7 +211,7 @@ impl From for AptosFeatureFlag { match f { FeatureFlag::CodeDependencyCheck => AptosFeatureFlag::CODE_DEPENDENCY_CHECK, FeatureFlag::CollectAndDistributeGasFees => { - AptosFeatureFlag::COLLECT_AND_DISTRIBUTE_GAS_FEES + AptosFeatureFlag::_DEPRECATED_COLLECT_AND_DISTRIBUTE_GAS_FEES }, FeatureFlag::TreatFriendAsPrivate => AptosFeatureFlag::TREAT_FRIEND_AS_PRIVATE, FeatureFlag::Sha512AndRipeMd160Natives => { @@ -353,7 +353,7 @@ impl From for FeatureFlag { fn from(f: AptosFeatureFlag) -> Self { match f { AptosFeatureFlag::CODE_DEPENDENCY_CHECK => FeatureFlag::CodeDependencyCheck, - AptosFeatureFlag::COLLECT_AND_DISTRIBUTE_GAS_FEES => { + AptosFeatureFlag::_DEPRECATED_COLLECT_AND_DISTRIBUTE_GAS_FEES => { FeatureFlag::CollectAndDistributeGasFees }, AptosFeatureFlag::TREAT_FRIEND_AS_PRIVATE => FeatureFlag::TreatFriendAsPrivate, diff --git a/aptos-move/e2e-move-tests/src/tests/mod.rs b/aptos-move/e2e-move-tests/src/tests/mod.rs index efcafc20fd1542..e76821c146092b 100644 --- a/aptos-move/e2e-move-tests/src/tests/mod.rs +++ b/aptos-move/e2e-move-tests/src/tests/mod.rs @@ -52,7 +52,6 @@ mod test_self; mod token_event_store; mod token_objects; mod transaction_context; -mod transaction_fee; mod type_too_large; mod vector_numeric_address; mod vm; diff --git a/aptos-move/e2e-move-tests/src/tests/transaction_fee.rs b/aptos-move/e2e-move-tests/src/tests/transaction_fee.rs deleted file mode 100644 index 5f134c35ff8414..00000000000000 --- a/aptos-move/e2e-move-tests/src/tests/transaction_fee.rs +++ /dev/null @@ -1,530 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -use crate::{ - assert_success, get_stake_pool, setup_staking, tests::common, transaction_fee, MoveHarness, -}; -use aptos_cached_packages::aptos_stdlib; -use aptos_language_e2e_tests::{account::Account, executor::FakeExecutor}; -use aptos_types::{ - account_address::AccountAddress, - on_chain_config::FeatureFlag, - transaction::{SignedTransaction, TransactionArgument, TransactionStatus}, -}; -use once_cell::sync::Lazy; -use rand::{ - distributions::Uniform, - rngs::{OsRng, StdRng}, - Rng, SeedableRng, -}; -use std::collections::BTreeMap; - -pub static PROPOSAL_SCRIPTS: Lazy>> = Lazy::new(build_scripts); - -fn build_scripts() -> BTreeMap> { - let package_folder = "transaction_fee.data"; - let package_names = vec![ - "initialize_collection", - "enable_collection", - "disable_collection", - "upgrade_burn_percentage", - "remove_validator", - ]; - common::build_scripts(package_folder, package_names) -} - -// Constants for calculating rewards for validators at the end of each epoch. -const INITIAL_STAKE_AMOUNT: u64 = 25_000_000; -const REWARDS_RATE_DENOMINATOR: u64 = 1_000_000_000; - -// Each epoch takes 1 hour in genesis config for tests. -const NUM_EPOCHS_IN_A_YEAR: u64 = 365 * 24; -const REWARDS_RATE: u64 = (10 * REWARDS_RATE_DENOMINATOR / 100) / NUM_EPOCHS_IN_A_YEAR; - -/// Holds all information about the current state of the chain, including -/// accounts of users, validators, etc. -struct TestUniverse { - harness: MoveHarness, - core_resources: Account, - validators: Vec, - users: Vec, -} - -// Make sure the number of users in this test universe is large enough. -const NUM_USERS: usize = 200; - -impl TestUniverse { - /// Creates a new testing universe with all necessary accounts created. - pub fn new(num_validators: usize) -> Self { - let executor = FakeExecutor::from_head_genesis().set_parallel(); - let mut harness = MoveHarness::new_with_executor(executor); - harness.set_default_gas_unit_price(1); - let core_resources = - harness.new_account_at(AccountAddress::from_hex_literal("0xA550C18").unwrap()); - let validators: Vec = (0..num_validators) - .map(|idx| { - harness.new_account_at( - AccountAddress::from_hex_literal(format!("0xa{}", idx).as_str()).unwrap(), - ) - }) - .collect(); - let users: Vec = (0..NUM_USERS) - .map(|idx| { - harness.new_account_at( - AccountAddress::from_hex_literal(format!("0xb{}", idx).as_str()).unwrap(), - ) - }) - .collect(); - Self { - harness, - core_resources, - validators, - users, - } - } - - /// Initializes validators with the given stake amount. - pub fn set_up_validators(&mut self, stake_amount: u64) { - self.validators.iter().for_each(|validator| { - assert_success!(setup_staking(&mut self.harness, validator, stake_amount)); - }); - self.harness.new_epoch(); - } - - /// Creates a block of p2p transactions in the universe. - pub fn create_block(&mut self, num_txns: usize) -> Vec { - let mut rng = StdRng::from_seed(OsRng.gen()); - let num_users = self.users.len(); - (0..num_txns) - .map(|_| { - // Select random users. - let src_account = &self.users[rng.sample(Uniform::new(0, num_users))]; - let dst_account = &self.users[rng.sample(Uniform::new(0, num_users))]; - - // Create a new p2p transaction. - self.harness.create_transaction_payload( - src_account, - aptos_stdlib::aptos_coin_transfer(*dst_account.address(), 1), - ) - }) - .collect() - } - - /// Injects a governance proposal script into transaction block. - pub fn inject_proposal_into_block( - &mut self, - block: &mut Vec, - proposal_idx: usize, - package_name: &str, - args: Vec, - ) { - let script_code = PROPOSAL_SCRIPTS - .get(package_name) - .expect("proposal script should be built"); - let sender = &self.core_resources; - let txn = self - .harness - .create_script(sender, script_code.clone(), vec![], args); - - debug_assert!(proposal_idx <= block.len()); - block.insert(proposal_idx, txn); - } - - /// Returns the total supply of AptosCoin in the universe. - pub fn read_total_supply(&mut self) -> u128 { - self.harness.executor.read_coin_supply().unwrap() - } -} - -/// For the given transaction outputs, calculates how much gas the block costs. -/// If there was a reconfiguration during the block execution, the cost is split -/// into before transaction triggering reconfiguration, and the cost of -/// transaction (governance proposal) triggering the reconfiguration. Note that -/// all outputs after reconfiguration should be Retry. -fn calculate_gas_used(outputs: Vec<(TransactionStatus, u64)>) -> (u64, u64) { - let mut found_reconfig = false; - let mut gas_used_for_reconfig = 0; - let mut total_gas_used = 0; - for (status, gas_used) in outputs { - total_gas_used += gas_used; - - if let TransactionStatus::Retry = status { - if !found_reconfig { - found_reconfig = true; - } - debug_assert!(gas_used == 0); - } else if !found_reconfig { - gas_used_for_reconfig = gas_used; - } - } - if !found_reconfig { - gas_used_for_reconfig = 0; - } - ( - total_gas_used - gas_used_for_reconfig, - gas_used_for_reconfig, - ) -} - -/// Tests a standard flow of collecting fees without any edge cases. -fn test_fee_collection_and_distribution_flow(burn_percentage: u8) { - let num_validators = 1; - let mut universe = TestUniverse::new(num_validators); - transaction_fee::initialize_fee_collection_and_distribution( - &mut universe.harness, - burn_percentage, - ); - universe - .harness - .enable_features(vec![FeatureFlag::COLLECT_AND_DISTRIBUTE_GAS_FEES], vec![]); - - let mut stake_amount = INITIAL_STAKE_AMOUNT; - universe.set_up_validators(stake_amount); - let rewards_per_epoch = stake_amount * REWARDS_RATE / REWARDS_RATE_DENOMINATOR; - assert_eq!(rewards_per_epoch, 285); - - // Run a single block and record how much gas it costs. Since fee collection - // is enabled, this amount is stored in aggregatable coin. - let validator_addr = *universe.validators[0].address(); - let txns = universe.create_block(1000); - - let mut total_supply = universe.read_total_supply(); - let outputs = universe - .harness - .run_block_with_metadata(validator_addr, vec![], txns); - let (p2p_gas, proposal_gas) = calculate_gas_used(outputs); - assert_eq!(proposal_gas, 0); - - let burnt_amount = (burn_percentage as u64) * p2p_gas / 100; - let collected_amount = p2p_gas - burnt_amount; - - // Drain aggregatable coin in the next block. - universe - .harness - .new_block_with_metadata(validator_addr, vec![]); - total_supply -= burnt_amount as u128; - - // Check that the right fraction was burnt. - assert_eq!(universe.read_total_supply(), total_supply); - - // On the new epoch, the collected fees are processed and added to the stake - // pool. - universe.harness.new_epoch(); - stake_amount += rewards_per_epoch + collected_amount; - assert_eq!( - get_stake_pool(&universe.harness, &validator_addr).active, - stake_amount - ); -} - -/// Tests if fees collection can be enabled by the governance proposal and how -/// fees are collected on the block boundary. -fn test_initialize_and_enable_fee_collection_and_distribution(burn_percentage: u8) { - let num_validators = 1; - let mut universe = TestUniverse::new(num_validators); - - let mut stake_amount = INITIAL_STAKE_AMOUNT; - universe.set_up_validators(stake_amount); - let rewards_per_epoch = stake_amount * REWARDS_RATE / REWARDS_RATE_DENOMINATOR; - assert_eq!(rewards_per_epoch, 285); - - // Create a block of transactions such that: - // 1. First 10 transactions are p2p. - // 2. A single transaction placing resources on chain. - // 3. Another 10 transactions are p2p. - // 4. A single transaction enabling fees collection. - // 5. Remaining transactions are p2p (should end up being Retry). - let mut txns = universe.create_block(50); - universe.inject_proposal_into_block(&mut txns, 10, "initialize_collection", vec![ - TransactionArgument::U8(burn_percentage), - ]); - universe.inject_proposal_into_block(&mut txns, 21, "enable_collection", vec![]); - - // Simulate block execution. - let mut total_supply = universe.read_total_supply(); - let validator_addr = *universe.validators[0].address(); - let outputs = universe - .harness - .run_block_with_metadata(validator_addr, vec![], txns); - let (gas_used, proposal_gas) = calculate_gas_used(outputs); - - // Reconfiguration triggers distributing rewards. - total_supply -= gas_used as u128; - total_supply += rewards_per_epoch as u128; - stake_amount += rewards_per_epoch; - assert_eq!(universe.read_total_supply(), total_supply); - assert_eq!( - get_stake_pool(&universe.harness, &validator_addr).active, - stake_amount - ); - - // In the previous block, the fee was only collected for the last script - // transaction which enabled the feature. In this block, we drain - // aggregatable coin and try to assign the fee to the validator. Since the - // proposer is not set (when feature flag was enabled), the fee is simply - // burnt and the stake pool should have the same value. - universe - .harness - .new_block_with_metadata(validator_addr, vec![]); - total_supply -= proposal_gas as u128; - assert_eq!(universe.read_total_supply(), total_supply); - assert_eq!( - get_stake_pool(&universe.harness, &validator_addr).active, - stake_amount - ); -} - -/// Tests fee collection can be safely disabled. The corner case here is that by disabling -/// the flag, we cannot distribute fees anymore unless it is done beforehand. -fn test_disable_fee_collection(burn_percentage: u8) { - let num_validators = 1; - let mut universe = TestUniverse::new(num_validators); - transaction_fee::initialize_fee_collection_and_distribution( - &mut universe.harness, - burn_percentage, - ); - universe - .harness - .enable_features(vec![FeatureFlag::COLLECT_AND_DISTRIBUTE_GAS_FEES], vec![]); - - let mut stake_amount = INITIAL_STAKE_AMOUNT; - universe.set_up_validators(stake_amount); - let rewards_per_epoch = stake_amount * REWARDS_RATE / REWARDS_RATE_DENOMINATOR; - assert_eq!(rewards_per_epoch, 285); - - // Create a block of transactions such that: - // 1. First 10 transactions are p2p. - // 2. A single transaction disabling fees collection. - // 3. Remaining transactions are p2p (should end up being Retry). - let mut txns = universe.create_block(100); - universe.inject_proposal_into_block(&mut txns, 10, "disable_collection", vec![]); - let validator_addr = *universe.validators[0].address(); - - // Simulate block execution. - let mut total_supply = universe.read_total_supply(); - let outputs = universe - .harness - .run_block_with_metadata(validator_addr, vec![], txns); - let (p2p_gas, proposal_gas) = calculate_gas_used(outputs); - - // Calculate the fees taht are supposed to be collected before the feature - // is disabled. - let burnt_amount = (burn_percentage as u64) * p2p_gas / 100; - let collected_amount = p2p_gas - burnt_amount; - - // Reconfiguration triggers distribution of both rewards and fees. - stake_amount += rewards_per_epoch + collected_amount; - total_supply += rewards_per_epoch as u128; - total_supply -= burnt_amount as u128; - assert_eq!( - get_stake_pool(&universe.harness, &validator_addr).active, - stake_amount - ); - - // Gas for the proposal should be burnt together with the fraction of the - // fees. - universe - .harness - .new_block_with_metadata(validator_addr, vec![]); - total_supply -= proposal_gas as u128; - assert_eq!(universe.read_total_supply(), total_supply); -} - -/// Tests that the fees collected prior to the upgrade use the right burn -/// percentage for calculations. -fn test_upgrade_burn_percentage(burn_percentage: u8) { - let num_validators = 2; - let mut universe = TestUniverse::new(num_validators); - transaction_fee::initialize_fee_collection_and_distribution( - &mut universe.harness, - burn_percentage, - ); - universe - .harness - .enable_features(vec![FeatureFlag::COLLECT_AND_DISTRIBUTE_GAS_FEES], vec![]); - - let mut stake_amount = INITIAL_STAKE_AMOUNT; - universe.set_up_validators(stake_amount); - - // Upgrade to the opposite value. - let new_burn_percentage = 100 - burn_percentage; - - // Create a block of transactions such that: - // 1. First 10 transactions are p2p. - // 2. A single transaction upgrading the burn percentage. - // 3. Remaining transactions are p2p (should end up being Retry). - let mut txns = universe.create_block(100); - universe.inject_proposal_into_block(&mut txns, 10, "upgrade_burn_percentage", vec![ - TransactionArgument::U8(new_burn_percentage), - ]); - let validator_addr = *universe.validators[0].address(); - - // Simulate block execution. - let mut total_supply = universe.read_total_supply(); - let outputs = universe - .harness - .run_block_with_metadata(validator_addr, vec![], txns); - let (p2p_gas, proposal_gas) = calculate_gas_used(outputs); - - let burnt_amount = (burn_percentage as u64) * p2p_gas / 100; - let collected_amount = p2p_gas - burnt_amount; - - // Compute rewards for this epoch. - let rewards_per_epoch = stake_amount * REWARDS_RATE / REWARDS_RATE_DENOMINATOR; - assert_eq!(rewards_per_epoch, 285); - - // Reconfiguration triggers distribution of rewards and fees. - stake_amount += rewards_per_epoch + collected_amount; - total_supply += rewards_per_epoch as u128; - total_supply -= burnt_amount as u128; - assert_eq!( - get_stake_pool(&universe.harness, &validator_addr).active, - stake_amount - ); - - // Gas for the proposal should be burnt together with fraction of fees. - universe - .harness - .new_block_with_metadata(validator_addr, vec![]); - total_supply -= proposal_gas as u128; - assert_eq!(universe.read_total_supply(), total_supply); - - // Now check that the new burn percentage works correctly. - let txns = universe.create_block(100); - total_supply = universe.read_total_supply(); - let outputs = universe - .harness - .run_block_with_metadata(validator_addr, vec![], txns); - let (gas_used, proposal_gas) = calculate_gas_used(outputs); - assert_eq!(proposal_gas, 0); - - let burnt_amount = (new_burn_percentage as u64) * gas_used / 100; - let collected_amount = gas_used - burnt_amount; - - // Check that the new fraction of fees is burnt. - universe - .harness - .new_block_with_metadata(validator_addr, vec![]); - total_supply -= burnt_amount as u128; - assert_eq!(universe.read_total_supply(), total_supply); - - // Check fees are distributed during the next epoch. Make sure to - // recalculate the rewards as well. - universe.harness.new_epoch(); - - // Compute rewards for this epoch. - let rewards_per_epoch = stake_amount * REWARDS_RATE / REWARDS_RATE_DENOMINATOR; - stake_amount += rewards_per_epoch + collected_amount; - assert_eq!( - get_stake_pool(&universe.harness, &validator_addr).active, - stake_amount - ); -} - -/// Tests that if validator running the block is removed, it still receives -/// previously collected fees. -fn test_leaving_validator_is_rewarded(burn_percentage: u8) { - let num_validators = 2; - let mut universe = TestUniverse::new(num_validators); - transaction_fee::initialize_fee_collection_and_distribution( - &mut universe.harness, - burn_percentage, - ); - universe - .harness - .enable_features(vec![FeatureFlag::COLLECT_AND_DISTRIBUTE_GAS_FEES], vec![]); - - let mut stake_amount = INITIAL_STAKE_AMOUNT; - universe.set_up_validators(stake_amount); - let rewards_per_epoch = stake_amount * REWARDS_RATE / REWARDS_RATE_DENOMINATOR; - assert_eq!(rewards_per_epoch, 285); - - // Create a block of transactions such that: - // 1. First 10 transactions are p2p. - // 2. A single transaction removing the validator. - // 3. Remaining transactions are p2p (should end up being Retry). - let removed_validator_addr = *universe.validators[0].address(); - let mut txns = universe.create_block(20); - universe.inject_proposal_into_block(&mut txns, 10, "remove_validator", vec![ - TransactionArgument::Address(removed_validator_addr), - ]); - - // Simulate block execution and calculate how much gas was used for - // transactions and for the governance proposal. - let mut total_supply = universe.read_total_supply(); - let outputs = universe - .harness - .run_block_with_metadata(removed_validator_addr, vec![], txns); - let (p2p_gas, proposal_gas) = calculate_gas_used(outputs); - - let burnt_amount = (burn_percentage as u64) * p2p_gas / 100; - let collected_amount = p2p_gas - burnt_amount; - - // Reconfiguration triggers distributing rewards and fees. - stake_amount += rewards_per_epoch + collected_amount; - total_supply += rewards_per_epoch as u128; - total_supply -= burnt_amount as u128; - assert_eq!( - get_stake_pool(&universe.harness, &removed_validator_addr).active, - stake_amount - ); - - let remaining_validator_addr = *universe.validators[1].address(); - universe - .harness - .new_block_with_metadata(remaining_validator_addr, vec![]); - total_supply -= proposal_gas as u128; - assert_eq!(universe.read_total_supply(), total_supply); -} - -#[test] -fn test_fee_collection_and_distribution_for_burn_percentages() { - // Test multiple burn percentages including the cases of 0 and 100. - for burn_percentage in [0, 50, 100] { - test_fee_collection_and_distribution_flow(burn_percentage); - test_initialize_and_enable_fee_collection_and_distribution(burn_percentage); - test_disable_fee_collection(burn_percentage); - test_upgrade_burn_percentage(burn_percentage); - test_leaving_validator_is_rewarded(burn_percentage); - } -} - -#[test] -/// Tests that fees for proposals are never leaked to the next block and are -/// always burnt. -fn test_block_single_proposal() { - let num_validators = 1; - let mut universe = TestUniverse::new(num_validators); - transaction_fee::initialize_fee_collection_and_distribution(&mut universe.harness, 100); - - let stake_amount = INITIAL_STAKE_AMOUNT; - universe.set_up_validators(stake_amount); - let rewards_per_epoch = stake_amount * REWARDS_RATE / REWARDS_RATE_DENOMINATOR; - assert_eq!(rewards_per_epoch, 285); - - // Create block with a single transaction: governance proposal to enable - // fee collection. This proposal ends the epoch. - let mut txns = vec![]; - universe.inject_proposal_into_block(&mut txns, 0, "enable_collection", vec![]); - let validator_addr = *universe.validators[0].address(); - - let mut total_supply = universe.read_total_supply(); - let outputs = universe - .harness - .run_block_with_metadata(validator_addr, vec![], txns); - let proposal_gas = outputs[1].1; - - // After reconfiguration rewards will be distributed. Because there are no - // other transactions, there is nothing to drain. However, this still should - // unset the proposer so that the next block burns the proposal fee. - total_supply += rewards_per_epoch as u128; - assert_eq!(universe.read_total_supply(), total_supply); - - // Ensure the fees are not leaked to the next block. This block must burn - // the proposal fee. - universe - .harness - .new_block_with_metadata(validator_addr, vec![]); - total_supply -= proposal_gas as u128; - assert_eq!(universe.read_total_supply(), total_supply); -} diff --git a/aptos-move/framework/aptos-framework/doc/aptos_governance.md b/aptos-move/framework/aptos-framework/doc/aptos_governance.md index 4daf73a12bded5..192d334caadd8a 100644 --- a/aptos-move/framework/aptos-framework/doc/aptos_governance.md +++ b/aptos-move/framework/aptos-framework/doc/aptos_governance.md @@ -2481,6 +2481,80 @@ The same as spec of + + +
schema CreateProposalAbortsIf {
+    proposer: &signer;
+    stake_pool: address;
+    execution_hash: vector<u8>;
+    metadata_location: vector<u8>;
+    metadata_hash: vector<u8>;
+    include VotingGetDelegatedVoterAbortsIf { sign: proposer };
+    include AbortsIfNotGovernanceConfig;
+    include GetVotingPowerAbortsIf { pool_address: stake_pool };
+    let staking_config = global<staking_config::StakingConfig>(@aptos_framework);
+    let allow_validator_set_change = staking_config.allow_validator_set_change;
+    let stake_pool_res = global<stake::StakePool>(stake_pool);
+    let stake_balance_0 = stake_pool_res.active.value + stake_pool_res.pending_active.value + stake_pool_res.pending_inactive.value;
+    let stake_balance_1 = stake_pool_res.active.value + stake_pool_res.pending_inactive.value;
+    let stake_balance_2 = 0;
+    let governance_config = global<GovernanceConfig>(@aptos_framework);
+    let required_proposer_stake = governance_config.required_proposer_stake;
+    // This enforces high-level requirement 2:
+    aborts_if allow_validator_set_change && stake_balance_0 < required_proposer_stake;
+    aborts_if !allow_validator_set_change && stake::spec_is_current_epoch_validator(stake_pool) && stake_balance_1 < required_proposer_stake;
+    aborts_if !allow_validator_set_change && !stake::spec_is_current_epoch_validator(stake_pool) && stake_balance_2 < required_proposer_stake;
+    aborts_if !exists<timestamp::CurrentTimeMicroseconds>(@aptos_framework);
+    let current_time = timestamp::spec_now_seconds();
+    let proposal_expiration = current_time + governance_config.voting_duration_secs;
+    aborts_if stake_pool_res.locked_until_secs < proposal_expiration;
+    include CreateProposalMetadataAbortsIf;
+    let addr = aptos_std::type_info::type_of<AptosCoin>().account_address;
+    aborts_if !exists<coin::CoinInfo<AptosCoin>>(addr);
+    let maybe_supply = global<coin::CoinInfo<AptosCoin>>(addr).supply;
+    let supply = option::spec_borrow(maybe_supply);
+    let total_supply = aptos_framework::optional_aggregator::optional_aggregator_value(supply);
+    let early_resolution_vote_threshold_value = total_supply / 2 + 1;
+    aborts_if option::spec_is_some(maybe_supply) && governance_config.min_voting_threshold > early_resolution_vote_threshold_value;
+    aborts_if len(execution_hash) == 0;
+    aborts_if !exists<voting::VotingForum<GovernanceProposal>>(@aptos_framework);
+    let voting_forum = global<voting::VotingForum<GovernanceProposal>>(@aptos_framework);
+    let proposal_id = voting_forum.next_proposal_id;
+    aborts_if proposal_id + 1 > MAX_U64;
+    let post post_voting_forum = global<voting::VotingForum<GovernanceProposal>>(@aptos_framework);
+    let post post_next_proposal_id = post_voting_forum.next_proposal_id;
+    ensures post_next_proposal_id == proposal_id + 1;
+    aborts_if !string::spec_internal_check_utf8(voting::IS_MULTI_STEP_PROPOSAL_KEY);
+    aborts_if !string::spec_internal_check_utf8(voting::IS_MULTI_STEP_PROPOSAL_IN_EXECUTION_KEY);
+    aborts_if table::spec_contains(voting_forum.proposals,proposal_id);
+    ensures table::spec_contains(post_voting_forum.proposals, proposal_id);
+    aborts_if !exists<GovernanceEvents>(@aptos_framework);
+}
+
+ + + + + + + +
schema VotingGetDelegatedVoterAbortsIf {
+    stake_pool: address;
+    sign: signer;
+    let addr = signer::address_of(sign);
+    let stake_pool_res = global<stake::StakePool>(stake_pool);
+    aborts_if !exists<stake::StakePool>(stake_pool);
+    aborts_if stake_pool_res.delegated_voter != addr;
+}
+
+ + @@ -2929,7 +3003,6 @@ Address @aptos_framework must exist ApprovedExecutionHashes and GovernancePropos framework: aptos_framework }; include stake::GetReconfigStartTimeRequirement; -include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply; requires chain_status::is_operating(); requires exists<stake::ValidatorFees>(@aptos_framework); requires exists<CoinInfo<AptosCoin>>(@aptos_framework); @@ -3006,7 +3079,6 @@ Address @aptos_framework must exist GovernanceConfig and GovernanceEvents. framework: aptos_framework }; include stake::GetReconfigStartTimeRequirement; -include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply; requires chain_status::is_operating(); requires exists<stake::ValidatorFees>(@aptos_framework); requires exists<CoinInfo<AptosCoin>>(@aptos_framework); diff --git a/aptos-move/framework/aptos-framework/doc/block.md b/aptos-move/framework/aptos-framework/doc/block.md index f5c44300077320..623d98b6a948ac 100644 --- a/aptos-move/framework/aptos-framework/doc/block.md +++ b/aptos-move/framework/aptos-framework/doc/block.md @@ -54,7 +54,6 @@ This module defines a struct storing the metadata of the block and new block eve use 0x1::system_addresses; use 0x1::table_with_length; use 0x1::timestamp; -use 0x1::transaction_fee;
@@ -616,15 +615,6 @@ Return epoch interval in seconds. }; emit_new_block_event(vm, &mut block_metadata_ref.new_block_events, new_block_event, new_block_event_v2); - if (features::collect_and_distribute_gas_fees()) { - // Assign the fees collected from the previous block to the previous block proposer. - // If for any reason the fees cannot be assigned, this function burns the collected coins. - transaction_fee::process_collected_fees(); - // Set the proposer of this block as the receiver of the fees, so that the fees for this - // block are assigned to the right account. - transaction_fee::register_proposer_for_fee_collection(proposer); - }; - // Performance scores have to be updated before the epoch transition as the transaction that triggers the // transition is the last block in the previous epoch. stake::update_performance_statistics(proposer_index, failed_proposer_indices); @@ -1088,6 +1078,69 @@ The number of new events created does not exceed MAX_U64. + + + + +
schema BlockRequirement {
+    vm: signer;
+    hash: address;
+    epoch: u64;
+    round: u64;
+    proposer: address;
+    failed_proposer_indices: vector<u64>;
+    previous_block_votes_bitvec: vector<u8>;
+    timestamp: u64;
+    requires chain_status::is_operating();
+    requires system_addresses::is_vm(vm);
+    // This enforces high-level requirement 4:
+    requires proposer == @vm_reserved || stake::spec_is_current_epoch_validator(proposer);
+    requires (proposer == @vm_reserved) ==> (timestamp::spec_now_microseconds() == timestamp);
+    requires (proposer != @vm_reserved) ==> (timestamp::spec_now_microseconds() < timestamp);
+    requires exists<stake::ValidatorFees>(@aptos_framework);
+    requires exists<CoinInfo<AptosCoin>>(@aptos_framework);
+    include staking_config::StakingRewardsConfigRequirement;
+}
+
+ + + + + + + +
schema Initialize {
+    aptos_framework: signer;
+    epoch_interval_microsecs: u64;
+    let addr = signer::address_of(aptos_framework);
+    // This enforces high-level requirement 2:
+    aborts_if addr != @aptos_framework;
+    aborts_if epoch_interval_microsecs == 0;
+    aborts_if exists<BlockResource>(addr);
+    aborts_if exists<CommitHistory>(addr);
+    ensures exists<BlockResource>(addr);
+    ensures exists<CommitHistory>(addr);
+    ensures global<BlockResource>(addr).height == 0;
+}
+
+ + + + + + + +
schema NewEventHandle {
+    aptos_framework: signer;
+    let addr = signer::address_of(aptos_framework);
+    let account = global<account::Account>(addr);
+    aborts_if !exists<account::Account>(addr);
+    aborts_if account.guid_creation_num + 2 > MAX_U64;
+}
+
+ + + ### Function `update_epoch_interval_microsecs` diff --git a/aptos-move/framework/aptos-framework/doc/coin.md b/aptos-move/framework/aptos-framework/doc/coin.md index 07e97171f99b19..9d9b5de80adddd 100644 --- a/aptos-move/framework/aptos-framework/doc/coin.md +++ b/aptos-move/framework/aptos-framework/doc/coin.md @@ -55,11 +55,6 @@ This module provides the foundation for typesafe Coins. - [Function `borrow_paired_burn_ref`](#0x1_coin_borrow_paired_burn_ref) - [Function `initialize_supply_config`](#0x1_coin_initialize_supply_config) - [Function `allow_supply_upgrades`](#0x1_coin_allow_supply_upgrades) -- [Function `initialize_aggregatable_coin`](#0x1_coin_initialize_aggregatable_coin) -- [Function `is_aggregatable_coin_zero`](#0x1_coin_is_aggregatable_coin_zero) -- [Function `drain_aggregatable_coin`](#0x1_coin_drain_aggregatable_coin) -- [Function `merge_aggregatable_coin`](#0x1_coin_merge_aggregatable_coin) -- [Function `collect_into_aggregatable_coin`](#0x1_coin_collect_into_aggregatable_coin) - [Function `calculate_amount_to_withdraw`](#0x1_coin_calculate_amount_to_withdraw) - [Function `maybe_convert_to_fungible_store`](#0x1_coin_maybe_convert_to_fungible_store) - [Function `migrate_to_fungible_store`](#0x1_coin_migrate_to_fungible_store) @@ -109,11 +104,6 @@ This module provides the foundation for typesafe Coins. - [Function `fungible_asset_to_coin`](#@Specification_1_fungible_asset_to_coin) - [Function `initialize_supply_config`](#@Specification_1_initialize_supply_config) - [Function `allow_supply_upgrades`](#@Specification_1_allow_supply_upgrades) - - [Function `initialize_aggregatable_coin`](#@Specification_1_initialize_aggregatable_coin) - - [Function `is_aggregatable_coin_zero`](#@Specification_1_is_aggregatable_coin_zero) - - [Function `drain_aggregatable_coin`](#@Specification_1_drain_aggregatable_coin) - - [Function `merge_aggregatable_coin`](#@Specification_1_merge_aggregatable_coin) - - [Function `collect_into_aggregatable_coin`](#@Specification_1_collect_into_aggregatable_coin) - [Function `maybe_convert_to_fungible_store`](#@Specification_1_maybe_convert_to_fungible_store) - [Function `coin_address`](#@Specification_1_coin_address) - [Function `balance`](#@Specification_1_balance) @@ -148,7 +138,6 @@ This module provides the foundation for typesafe Coins.
use 0x1::account;
 use 0x1::aggregator;
-use 0x1::aggregator_factory;
 use 0x1::create_signer;
 use 0x1::error;
 use 0x1::event;
@@ -201,12 +190,11 @@ Main structure representing a coin/token in an account's custody.
 
 ## Struct `AggregatableCoin`
 
-Represents a coin with aggregator as its value. This allows to update
-the coin in every transaction avoiding read-modify-write conflicts. Only
-used for gas fees distribution by Aptos Framework (0x1).
+DEPRECATED
 
 
-
struct AggregatableCoin<CoinType> has store
+
#[deprecated]
+struct AggregatableCoin<CoinType> has store
 
@@ -2025,189 +2013,6 @@ or disallow upgradability of total supply. - - - - -## Function `initialize_aggregatable_coin` - -Creates a new aggregatable coin with value overflowing on limit. Note that this function can -only be called by Aptos Framework (0x1) account for now because of create_aggregator. - - -
public(friend) fun initialize_aggregatable_coin<CoinType>(aptos_framework: &signer): coin::AggregatableCoin<CoinType>
-
- - - -
-Implementation - - -
public(friend) fun initialize_aggregatable_coin<CoinType>(aptos_framework: &signer): AggregatableCoin<CoinType> {
-    let aggregator = aggregator_factory::create_aggregator(aptos_framework, MAX_U64);
-    AggregatableCoin<CoinType> {
-        value: aggregator,
-    }
-}
-
- - - -
- - - -## Function `is_aggregatable_coin_zero` - -Returns true if the value of aggregatable coin is zero. - - -
public(friend) fun is_aggregatable_coin_zero<CoinType>(coin: &coin::AggregatableCoin<CoinType>): bool
-
- - - -
-Implementation - - -
public(friend) fun is_aggregatable_coin_zero<CoinType>(coin: &AggregatableCoin<CoinType>): bool {
-    let amount = aggregator::read(&coin.value);
-    amount == 0
-}
-
- - - -
- - - -## Function `drain_aggregatable_coin` - -Drains the aggregatable coin, setting it to zero and returning a standard coin. - - -
public(friend) fun drain_aggregatable_coin<CoinType>(coin: &mut coin::AggregatableCoin<CoinType>): coin::Coin<CoinType>
-
- - - -
-Implementation - - -
public(friend) fun drain_aggregatable_coin<CoinType>(coin: &mut AggregatableCoin<CoinType>): Coin<CoinType> {
-    spec {
-        // TODO: The data invariant is not properly assumed from CollectedFeesPerBlock.
-        assume aggregator::spec_get_limit(coin.value) == MAX_U64;
-    };
-    let amount = aggregator::read(&coin.value);
-    assert!(amount <= MAX_U64, error::out_of_range(EAGGREGATABLE_COIN_VALUE_TOO_LARGE));
-    spec {
-        update aggregate_supply<CoinType> = aggregate_supply<CoinType> - amount;
-    };
-    aggregator::sub(&mut coin.value, amount);
-    spec {
-        update supply<CoinType> = supply<CoinType> + amount;
-    };
-    Coin<CoinType> {
-        value: (amount as u64),
-    }
-}
-
- - - -
- - - -## Function `merge_aggregatable_coin` - -Merges coin into aggregatable coin (dst_coin). - - -
public(friend) fun merge_aggregatable_coin<CoinType>(dst_coin: &mut coin::AggregatableCoin<CoinType>, coin: coin::Coin<CoinType>)
-
- - - -
-Implementation - - -
public(friend) fun merge_aggregatable_coin<CoinType>(
-    dst_coin: &mut AggregatableCoin<CoinType>,
-    coin: Coin<CoinType>
-) {
-    spec {
-        update supply<CoinType> = supply<CoinType> - coin.value;
-    };
-    let Coin { value } = coin;
-    let amount = (value as u128);
-    spec {
-        update aggregate_supply<CoinType> = aggregate_supply<CoinType> + amount;
-    };
-    aggregator::add(&mut dst_coin.value, amount);
-}
-
- - - -
- - - -## Function `collect_into_aggregatable_coin` - -Collects a specified amount of coin form an account into aggregatable coin. - - -
public(friend) fun collect_into_aggregatable_coin<CoinType>(account_addr: address, amount: u64, dst_coin: &mut coin::AggregatableCoin<CoinType>)
-
- - - -
-Implementation - - -
public(friend) fun collect_into_aggregatable_coin<CoinType>(
-    account_addr: address,
-    amount: u64,
-    dst_coin: &mut AggregatableCoin<CoinType>,
-) acquires CoinStore, CoinConversionMap, CoinInfo, PairedCoinType {
-    // Skip collecting if amount is zero.
-    if (amount == 0) {
-        return
-    };
-
-    let (coin_amount_to_collect, fa_amount_to_collect) = calculate_amount_to_withdraw<CoinType>(
-        account_addr,
-        amount
-    );
-    let coin = if (coin_amount_to_collect > 0) {
-        let coin_store = borrow_global_mut<CoinStore<CoinType>>(account_addr);
-        extract(&mut coin_store.coin, coin_amount_to_collect)
-    } else {
-        zero()
-    };
-    if (fa_amount_to_collect > 0) {
-        let store_addr = primary_fungible_store::primary_store_address(
-            account_addr,
-            option::destroy_some(paired_metadata<CoinType>())
-        );
-        let fa = fungible_asset::withdraw_internal(store_addr, fa_amount_to_collect);
-        merge(&mut coin, fungible_asset_to_coin<CoinType>(fa));
-    };
-    merge_aggregatable_coin(dst_coin, coin);
-}
-
- - -
@@ -3814,70 +3619,13 @@ initialize, initialize_internal, initialize_with_parallelizable_supply; - - - - -
fun spec_is_account_registered<CoinType>(account_addr: address): bool {
-   let paired_metadata_opt = spec_paired_metadata<CoinType>();
-   exists<CoinStore<CoinType>>(account_addr) || (option::spec_is_some(
-       paired_metadata_opt
-   ) && primary_fungible_store::spec_primary_store_exists(account_addr, option::spec_borrow(paired_metadata_opt)))
-}
-
- - - - - - - -
schema CoinSubAbortsIf<CoinType> {
-    amount: u64;
-    let addr = type_info::type_of<CoinType>().account_address;
-    let maybe_supply = global<CoinInfo<CoinType>>(addr).supply;
-    include (option::is_some(
-        maybe_supply
-    )) ==> optional_aggregator::SubAbortsIf { optional_aggregator: option::borrow(maybe_supply), value: amount };
-}
-
- - - - - - - -
schema CoinAddAbortsIf<CoinType> {
-    amount: u64;
-    let addr = type_info::type_of<CoinType>().account_address;
-    let maybe_supply = global<CoinInfo<CoinType>>(addr).supply;
-    include (option::is_some(
-        maybe_supply
-    )) ==> optional_aggregator::AddAbortsIf { optional_aggregator: option::borrow(maybe_supply), value: amount };
-}
-
- - - - - - - -
schema AbortsIfNotExistCoinInfo<CoinType> {
-    let addr = type_info::type_of<CoinType>().account_address;
-    aborts_if !exists<CoinInfo<CoinType>>(addr);
-}
-
- - - ### Struct `AggregatableCoin` -
struct AggregatableCoin<CoinType> has store
+
#[deprecated]
+struct AggregatableCoin<CoinType> has store
 
@@ -3976,107 +3724,6 @@ Can only be updated by @aptos_framework. - - -### Function `initialize_aggregatable_coin` - - -
public(friend) fun initialize_aggregatable_coin<CoinType>(aptos_framework: &signer): coin::AggregatableCoin<CoinType>
-
- - - - -
include system_addresses::AbortsIfNotAptosFramework { account: aptos_framework };
-include aggregator_factory::CreateAggregatorInternalAbortsIf;
-
- - - - - -### Function `is_aggregatable_coin_zero` - - -
public(friend) fun is_aggregatable_coin_zero<CoinType>(coin: &coin::AggregatableCoin<CoinType>): bool
-
- - - - -
aborts_if false;
-ensures result == (aggregator::spec_read(coin.value) == 0);
-
- - - - - -### Function `drain_aggregatable_coin` - - -
public(friend) fun drain_aggregatable_coin<CoinType>(coin: &mut coin::AggregatableCoin<CoinType>): coin::Coin<CoinType>
-
- - - - -
aborts_if aggregator::spec_read(coin.value) > MAX_U64;
-ensures result.value == aggregator::spec_aggregator_get_val(old(coin).value);
-
- - - - - -### Function `merge_aggregatable_coin` - - -
public(friend) fun merge_aggregatable_coin<CoinType>(dst_coin: &mut coin::AggregatableCoin<CoinType>, coin: coin::Coin<CoinType>)
-
- - - - -
let aggr = dst_coin.value;
-let post p_aggr = dst_coin.value;
-aborts_if aggregator::spec_aggregator_get_val(aggr)
-    + coin.value > aggregator::spec_get_limit(aggr);
-aborts_if aggregator::spec_aggregator_get_val(aggr)
-    + coin.value > MAX_U128;
-ensures aggregator::spec_aggregator_get_val(aggr) + coin.value == aggregator::spec_aggregator_get_val(p_aggr);
-
- - - - - -### Function `collect_into_aggregatable_coin` - - -
public(friend) fun collect_into_aggregatable_coin<CoinType>(account_addr: address, amount: u64, dst_coin: &mut coin::AggregatableCoin<CoinType>)
-
- - - - -
pragma verify = false;
-let aggr = dst_coin.value;
-let post p_aggr = dst_coin.value;
-let coin_store = global<CoinStore<CoinType>>(account_addr);
-let post p_coin_store = global<CoinStore<CoinType>>(account_addr);
-aborts_if amount > 0 && !exists<CoinStore<CoinType>>(account_addr);
-aborts_if amount > 0 && coin_store.coin.value < amount;
-aborts_if amount > 0 && aggregator::spec_aggregator_get_val(aggr)
-    + amount > aggregator::spec_get_limit(aggr);
-aborts_if amount > 0 && aggregator::spec_aggregator_get_val(aggr)
-    + amount > MAX_U128;
-ensures aggregator::spec_aggregator_get_val(aggr) + amount == aggregator::spec_aggregator_get_val(p_aggr);
-ensures coin_store.coin.value - amount == p_coin_store.coin.value;
-
- - - ### Function `maybe_convert_to_fungible_store` @@ -4215,6 +3862,64 @@ Get address by reflection. + + + + +
fun spec_is_account_registered<CoinType>(account_addr: address): bool {
+   let paired_metadata_opt = spec_paired_metadata<CoinType>();
+   exists<CoinStore<CoinType>>(account_addr) || (option::spec_is_some(
+       paired_metadata_opt
+   ) && primary_fungible_store::spec_primary_store_exists(account_addr, option::spec_borrow(paired_metadata_opt)))
+}
+
+ + + + + + + +
schema CoinSubAbortsIf<CoinType> {
+    amount: u64;
+    let addr = type_info::type_of<CoinType>().account_address;
+    let maybe_supply = global<CoinInfo<CoinType>>(addr).supply;
+    include (option::is_some(
+        maybe_supply
+    )) ==> optional_aggregator::SubAbortsIf { optional_aggregator: option::borrow(maybe_supply), value: amount };
+}
+
+ + + + + + + +
schema CoinAddAbortsIf<CoinType> {
+    amount: u64;
+    let addr = type_info::type_of<CoinType>().account_address;
+    let maybe_supply = global<CoinInfo<CoinType>>(addr).supply;
+    include (option::is_some(
+        maybe_supply
+    )) ==> optional_aggregator::AddAbortsIf { optional_aggregator: option::borrow(maybe_supply), value: amount };
+}
+
+ + + + + + + +
schema AbortsIfNotExistCoinInfo<CoinType> {
+    let addr = type_info::type_of<CoinType>().account_address;
+    aborts_if !exists<CoinInfo<CoinType>>(addr);
+}
+
+ + + ### Function `name` diff --git a/aptos-move/framework/aptos-framework/doc/consensus_config.md b/aptos-move/framework/aptos-framework/doc/consensus_config.md index ddceb292dbdeda..d1c06df33f1197 100644 --- a/aptos-move/framework/aptos-framework/doc/consensus_config.md +++ b/aptos-move/framework/aptos-framework/doc/consensus_config.md @@ -348,7 +348,6 @@ When setting now time must be later than last_reconfiguration_time.
pragma verify_duration_estimate = 600;
-include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply;
 include staking_config::StakingRewardsConfigRequirement;
 let addr = signer::address_of(account);
 // This enforces high-level requirement 2:
diff --git a/aptos-move/framework/aptos-framework/doc/execution_config.md b/aptos-move/framework/aptos-framework/doc/execution_config.md
index 06be205963675c..9c959addb23754 100644
--- a/aptos-move/framework/aptos-framework/doc/execution_config.md
+++ b/aptos-move/framework/aptos-framework/doc/execution_config.md
@@ -202,7 +202,6 @@ When setting now time must be later than last_reconfiguration_time.
 
 
pragma verify_duration_estimate = 600;
 let addr = signer::address_of(account);
-include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply;
 requires chain_status::is_genesis();
 requires exists<stake::ValidatorFees>(@aptos_framework);
 requires exists<staking_config::StakingRewardsConfig>(@aptos_framework);
diff --git a/aptos-move/framework/aptos-framework/doc/gas_schedule.md b/aptos-move/framework/aptos-framework/doc/gas_schedule.md
index ea4a92886698f5..2fd76a7e1f569f 100644
--- a/aptos-move/framework/aptos-framework/doc/gas_schedule.md
+++ b/aptos-move/framework/aptos-framework/doc/gas_schedule.md
@@ -528,7 +528,6 @@ Only used in reconfigurations to apply the pending stake::ValidatorFees>(@aptos_framework);
 requires exists<CoinInfo<AptosCoin>>(@aptos_framework);
 requires chain_status::is_genesis();
-include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply;
 include staking_config::StakingRewardsConfigRequirement;
 // This enforces high-level requirement 2:
 include system_addresses::AbortsIfNotAptosFramework{ account: aptos_framework };
@@ -624,7 +623,6 @@ Only used in reconfigurations to apply the pending stake::ValidatorFees>(@aptos_framework);
 requires exists<CoinInfo<AptosCoin>>(@aptos_framework);
 include system_addresses::AbortsIfNotAptosFramework{ account: aptos_framework };
-include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply;
 include staking_config::StakingRewardsConfigRequirement;
 aborts_if !exists<StorageGasConfig>(@aptos_framework);
 ensures global<StorageGasConfig>(@aptos_framework) == config;
diff --git a/aptos-move/framework/aptos-framework/doc/genesis.md b/aptos-move/framework/aptos-framework/doc/genesis.md
index 5fcac753d7489f..e767985fbd881c 100644
--- a/aptos-move/framework/aptos-framework/doc/genesis.md
+++ b/aptos-move/framework/aptos-framework/doc/genesis.md
@@ -1139,10 +1139,8 @@ The last step of genesis.
     requires chain_status::is_operating();
     requires len(execution_config) > 0;
     requires exists<staking_config::StakingRewardsConfig>(@aptos_framework);
-    requires exists<stake::ValidatorFees>(@aptos_framework);
     requires exists<coin::CoinInfo<AptosCoin>>(@aptos_framework);
     include CompareTimeRequires;
-    include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply;
 }
 
diff --git a/aptos-move/framework/aptos-framework/doc/reconfiguration.md b/aptos-move/framework/aptos-framework/doc/reconfiguration.md index 3415e0a820de1f..de8909bd158d71 100644 --- a/aptos-move/framework/aptos-framework/doc/reconfiguration.md +++ b/aptos-move/framework/aptos-framework/doc/reconfiguration.md @@ -44,7 +44,6 @@ to synchronize configuration changes for the validators. use 0x1::storage_gas; use 0x1::system_addresses; use 0x1::timestamp; -use 0x1::transaction_fee;
@@ -396,20 +395,6 @@ Signal validators to start using new configuration. Must be called from friend c reconfiguration_state::on_reconfig_start(); - // Reconfiguration "forces the block" to end, as mentioned above. Therefore, we must process the collected fees - // explicitly so that staking can distribute them. - // - // This also handles the case when a validator is removed due to the governance proposal. In particular, removing - // the validator causes a reconfiguration. We explicitly process fees, i.e. we drain aggregatable coin and populate - // the fees table, prior to calling `on_new_epoch()`. That call, in turn, distributes transaction fees for all active - // and pending_inactive validators, which include any validator that is to be removed. - if (features::collect_and_distribute_gas_fees()) { - // All transactions after reconfiguration are Retry. Therefore, when the next - // block starts and tries to assign/burn collected fees it will be just 0 and - // nothing will be assigned. - transaction_fee::process_collected_fees(); - }; - // Call stake to compute the new validator set and distribute rewards and transaction fees. stake::on_new_epoch(); storage_gas::on_reconfig(); @@ -731,7 +716,6 @@ Make sure the caller is admin and check the resource DisableReconfiguration. && timestamp::spec_now_microseconds() != global<Configuration>(@aptos_framework).last_reconfiguration_time; include features::spec_periodical_reward_rate_decrease_enabled() ==> staking_config::StakingRewardsConfigEnabledRequirement; include success ==> aptos_coin::ExistsAptosCoin; -include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply; aborts_if false; ensures success ==> global<Configuration>(@aptos_framework).epoch == old(global<Configuration>(@aptos_framework).epoch) + 1; ensures success ==> global<Configuration>(@aptos_framework).last_reconfiguration_time == timestamp::spec_now_microseconds(); diff --git a/aptos-move/framework/aptos-framework/doc/reconfiguration_with_dkg.md b/aptos-move/framework/aptos-framework/doc/reconfiguration_with_dkg.md index 005fd6f8249021..675414e2d1e894 100644 --- a/aptos-move/framework/aptos-framework/doc/reconfiguration_with_dkg.md +++ b/aptos-move/framework/aptos-framework/doc/reconfiguration_with_dkg.md @@ -209,7 +209,6 @@ Abort if no DKG is in progress. requires exists<CoinInfo<AptosCoin>>(@aptos_framework); include staking_config::StakingRewardsConfigRequirement; requires exists<stake::ValidatorFees>(@aptos_framework); - include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply; requires exists<features::Features>(@std); include config_buffer::OnNewEpochRequirement<version::Version>; include config_buffer::OnNewEpochRequirement<gas_schedule::GasScheduleV2>; diff --git a/aptos-move/framework/aptos-framework/doc/stake.md b/aptos-move/framework/aptos-framework/doc/stake.md index 5a199ef91f69d1..a5194e7fd3c33a 100644 --- a/aptos-move/framework/aptos-framework/doc/stake.md +++ b/aptos-move/framework/aptos-framework/doc/stake.md @@ -63,8 +63,6 @@ or if their stake drops below the min required, they would get removed at the en - [Resource `Ghost$ghost_active_num`](#0x1_stake_Ghost$ghost_active_num) - [Resource `Ghost$ghost_pending_inactive_num`](#0x1_stake_Ghost$ghost_pending_inactive_num) - [Constants](#@Constants_0) -- [Function `initialize_validator_fees`](#0x1_stake_initialize_validator_fees) -- [Function `add_transaction_fee`](#0x1_stake_add_transaction_fee) - [Function `get_lockup_secs`](#0x1_stake_get_lockup_secs) - [Function `get_remaining_lockup_secs`](#0x1_stake_get_remaining_lockup_secs) - [Function `get_stake`](#0x1_stake_get_stake) @@ -130,8 +128,6 @@ or if their stake drops below the min required, they would get removed at the en - [High-level Requirements](#high-level-req) - [Module-level Specification](#module-level-spec) - [Resource `ValidatorSet`](#@Specification_1_ValidatorSet) - - [Function `initialize_validator_fees`](#@Specification_1_initialize_validator_fees) - - [Function `add_transaction_fee`](#@Specification_1_add_transaction_fee) - [Function `get_validator_state`](#@Specification_1_get_validator_state) - [Function `initialize`](#@Specification_1_initialize) - [Function `remove_validators`](#@Specification_1_remove_validators) @@ -1447,11 +1443,11 @@ This allows the Stake module to mint rewards to stakers. ## Resource `ValidatorFees` -Stores transaction fees assigned to validators. All fees are distributed to validators -at the end of the epoch. +DEPRECATED -
struct ValidatorFees has key
+
#[deprecated]
+struct ValidatorFees has key
 
@@ -1882,68 +1878,6 @@ Validator status enum. We can switch to proper enum later once Move supports it. - - -## Function `initialize_validator_fees` - -Initializes the resource storing information about collected transaction fees per validator. -Used by transaction_fee.move to initialize fee collection and distribution. - - -
public(friend) fun initialize_validator_fees(aptos_framework: &signer)
-
- - - -
-Implementation - - -
public(friend) fun initialize_validator_fees(aptos_framework: &signer) {
-    system_addresses::assert_aptos_framework(aptos_framework);
-    assert!(
-        !exists<ValidatorFees>(@aptos_framework),
-        error::already_exists(EFEES_TABLE_ALREADY_EXISTS)
-    );
-    move_to(aptos_framework, ValidatorFees { fees_table: table::new() });
-}
-
- - - -
- - - -## Function `add_transaction_fee` - -Stores the transaction fee collected to the specified validator address. - - -
public(friend) fun add_transaction_fee(validator_addr: address, fee: coin::Coin<aptos_coin::AptosCoin>)
-
- - - -
-Implementation - - -
public(friend) fun add_transaction_fee(validator_addr: address, fee: Coin<AptosCoin>) acquires ValidatorFees {
-    let fees_table = &mut borrow_global_mut<ValidatorFees>(@aptos_framework).fees_table;
-    if (table::contains(fees_table, validator_addr)) {
-        let collected_fee = table::borrow_mut(fees_table, validator_addr);
-        coin::merge(collected_fee, fee);
-    } else {
-        table::add(fees_table, validator_addr, fee);
-    }
-}
-
- - - -
- ## Function `get_lockup_secs` @@ -3665,7 +3599,7 @@ power.
public(friend) fun on_new_epoch(
-) acquires StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+) acquires StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
     let validator_set = borrow_global_mut<ValidatorSet>(@aptos_framework);
     let config = staking_config::get();
     let validator_perf = borrow_global_mut<ValidatorPerformance>(@aptos_framework);
@@ -3826,7 +3760,7 @@ Return the ValidatorConsensusInfo of each current validator, sorted
 Implementation
 
 
-
public fun next_validator_consensus_infos(): vector<ValidatorConsensusInfo> acquires ValidatorSet, ValidatorPerformance, StakePool, ValidatorFees, ValidatorConfig {
+
public fun next_validator_consensus_infos(): vector<ValidatorConsensusInfo> acquires ValidatorSet, ValidatorPerformance, StakePool, ValidatorConfig {
     // Init.
     let cur_validator_set = borrow_global<ValidatorSet>(@aptos_framework);
     let staking_config = staking_config::get();
@@ -3881,25 +3815,16 @@ Return the ValidatorConsensusInfo of each current validator, sorted
             0
         };
 
-        let cur_fee = 0;
-        if (features::collect_and_distribute_gas_fees()) {
-            let fees_table = &borrow_global<ValidatorFees>(@aptos_framework).fees_table;
-            if (table::contains(fees_table, candidate.addr)) {
-                let fee_coin = table::borrow(fees_table, candidate.addr);
-                cur_fee = coin::value(fee_coin);
-            }
-        };
-
         let lockup_expired = get_reconfig_start_time_secs() >= stake_pool.locked_until_secs;
         spec {
-            assume cur_active + cur_pending_active + cur_reward + cur_fee <= MAX_U64;
-            assume cur_active + cur_pending_inactive + cur_pending_active + cur_reward + cur_fee <= MAX_U64;
+            assume cur_active + cur_pending_active + cur_reward <= MAX_U64;
+            assume cur_active + cur_pending_inactive + cur_pending_active + cur_reward <= MAX_U64;
         };
         let new_voting_power =
             cur_active
             + if (lockup_expired) { 0 } else { cur_pending_inactive }
             + cur_pending_active
-            + cur_reward + cur_fee;
+            + cur_reward;
 
         if (new_voting_power >= minimum_stake) {
             let config = *borrow_global<ValidatorConfig>(candidate.addr);
@@ -4078,7 +4003,7 @@ This function shouldn't abort.
     validator_perf: &ValidatorPerformance,
     pool_address: address,
     staking_config: &StakingConfig,
-) acquires StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorFees {
+) acquires StakePool, AptosCoinCapabilities, ValidatorConfig {
     let stake_pool = borrow_global_mut<StakePool>(pool_address);
     let validator_config = borrow_global<ValidatorConfig>(pool_address);
     let cur_validator_perf = vector::borrow(&validator_perf.validators, validator_config.validator_index);
@@ -4111,15 +4036,6 @@ This function shouldn't abort.
     // Pending active stake can now be active.
     coin::merge(&mut stake_pool.active, coin::extract_all(&mut stake_pool.pending_active));
 
-    // Additionally, distribute transaction fees.
-    if (features::collect_and_distribute_gas_fees()) {
-        let fees_table = &mut borrow_global_mut<ValidatorFees>(@aptos_framework).fees_table;
-        if (table::contains(fees_table, pool_address)) {
-            let coin = table::remove(fees_table, pool_address);
-            coin::merge(&mut stake_pool.active, coin);
-        };
-    };
-
     // Pending inactive stake is only fully unlocked and moved into inactive if the current lockup cycle has expired
     let current_lockup_expiration = stake_pool.locked_until_secs;
     if (get_reconfig_start_time_secs() >= current_lockup_expiration) {
@@ -4781,51 +4697,6 @@ Returns validator's next epoch voting power, including pending_active, active, a
 
 
 
-
-
-### Function `initialize_validator_fees`
-
-
-
public(friend) fun initialize_validator_fees(aptos_framework: &signer)
-
- - - - -
let aptos_addr = signer::address_of(aptos_framework);
-aborts_if !system_addresses::is_aptos_framework_address(aptos_addr);
-aborts_if exists<ValidatorFees>(aptos_addr);
-ensures exists<ValidatorFees>(aptos_addr);
-
- - - - - -### Function `add_transaction_fee` - - -
public(friend) fun add_transaction_fee(validator_addr: address, fee: coin::Coin<aptos_coin::AptosCoin>)
-
- - - - -
aborts_if !exists<ValidatorFees>(@aptos_framework);
-let fees_table = global<ValidatorFees>(@aptos_framework).fees_table;
-let post post_fees_table = global<ValidatorFees>(@aptos_framework).fees_table;
-let collected_fee = table::spec_get(fees_table, validator_addr);
-let post post_collected_fee = table::spec_get(post_fees_table, validator_addr);
-ensures if (table::spec_contains(fees_table, validator_addr)) {
-    post_collected_fee.value == collected_fee.value + fee.value
-} else {
-    table::spec_contains(post_fees_table, validator_addr) &&
-    table::spec_get(post_fees_table, validator_addr) == fee
-};
-
- - - ### Function `get_validator_state` @@ -5705,7 +5576,6 @@ Returns validator's next epoch voting power, including pending_active, active, a requires exists<StakingConfig>(@aptos_framework); requires exists<StakingRewardsConfig>(@aptos_framework) || !features::spec_periodical_reward_rate_decrease_enabled(); requires exists<timestamp::CurrentTimeMicroseconds>(@aptos_framework); - requires exists<ValidatorFees>(@aptos_framework); }
@@ -5800,16 +5670,9 @@ Returns validator's next epoch voting power, including pending_active, active, a let post post_stake_pool = global<StakePool>(pool_address); let post post_active_value = post_stake_pool.active.value; let post post_pending_inactive_value = post_stake_pool.pending_inactive.value; -let fees_table = global<ValidatorFees>(@aptos_framework).fees_table; -let post post_fees_table = global<ValidatorFees>(@aptos_framework).fees_table; let post post_inactive_value = post_stake_pool.inactive.value; ensures post_stake_pool.pending_active.value == 0; -ensures if (features::spec_is_enabled(features::COLLECT_AND_DISTRIBUTE_GAS_FEES) && table::spec_contains(fees_table, pool_address)) { - !table::spec_contains(post_fees_table, pool_address) && - post_active_value == stake_pool.active.value + rewards_amount_1 + stake_pool.pending_active.value + table::spec_get(fees_table, pool_address).value -} else { - post_active_value == stake_pool.active.value + rewards_amount_1 + stake_pool.pending_active.value -}; +ensures post_active_value == stake_pool.active.value + rewards_amount_1 + stake_pool.pending_active.value; ensures if (spec_get_reconfig_start_time_secs() >= stake_pool.locked_until_secs) { post_pending_inactive_value == 0 && post_inactive_value == stake_pool.inactive.value + stake_pool.pending_inactive.value + rewards_amount_2 @@ -5831,7 +5694,6 @@ Returns validator's next epoch voting power, including pending_active, active, a aborts_if !exists<ValidatorConfig>(pool_address); aborts_if global<ValidatorConfig>(pool_address).validator_index >= len(validator_perf.validators); let aptos_addr = type_info::type_of<AptosCoin>().account_address; - aborts_if !exists<ValidatorFees>(aptos_addr); let stake_pool = global<StakePool>(pool_address); include DistributeRewardsAbortsIf {stake: stake_pool.active}; include DistributeRewardsAbortsIf {stake: stake_pool.pending_inactive}; diff --git a/aptos-move/framework/aptos-framework/doc/transaction_fee.md b/aptos-move/framework/aptos-framework/doc/transaction_fee.md index 09e76f34e14db7..759746e055463c 100644 --- a/aptos-move/framework/aptos-framework/doc/transaction_fee.md +++ b/aptos-move/framework/aptos-framework/doc/transaction_fee.md @@ -13,14 +13,9 @@ This module provides an interface to burn or collect and redistribute transactio - [Struct `FeeStatement`](#0x1_transaction_fee_FeeStatement) - [Constants](#@Constants_0) - [Function `initialize_fee_collection_and_distribution`](#0x1_transaction_fee_initialize_fee_collection_and_distribution) -- [Function `is_fees_collection_enabled`](#0x1_transaction_fee_is_fees_collection_enabled) - [Function `upgrade_burn_percentage`](#0x1_transaction_fee_upgrade_burn_percentage) -- [Function `register_proposer_for_fee_collection`](#0x1_transaction_fee_register_proposer_for_fee_collection) -- [Function `burn_coin_fraction`](#0x1_transaction_fee_burn_coin_fraction) -- [Function `process_collected_fees`](#0x1_transaction_fee_process_collected_fees) - [Function `burn_fee`](#0x1_transaction_fee_burn_fee) - [Function `mint_and_refund`](#0x1_transaction_fee_mint_and_refund) -- [Function `collect_fee`](#0x1_transaction_fee_collect_fee) - [Function `store_aptos_coin_burn_cap`](#0x1_transaction_fee_store_aptos_coin_burn_cap) - [Function `convert_to_aptos_fa_burn_ref`](#0x1_transaction_fee_convert_to_aptos_fa_burn_ref) - [Function `store_aptos_coin_mint_cap`](#0x1_transaction_fee_store_aptos_coin_mint_cap) @@ -31,13 +26,8 @@ This module provides an interface to burn or collect and redistribute transactio - [Module-level Specification](#module-level-spec) - [Resource `CollectedFeesPerBlock`](#@Specification_1_CollectedFeesPerBlock) - [Function `initialize_fee_collection_and_distribution`](#@Specification_1_initialize_fee_collection_and_distribution) - - [Function `upgrade_burn_percentage`](#@Specification_1_upgrade_burn_percentage) - - [Function `register_proposer_for_fee_collection`](#@Specification_1_register_proposer_for_fee_collection) - - [Function `burn_coin_fraction`](#@Specification_1_burn_coin_fraction) - - [Function `process_collected_fees`](#@Specification_1_process_collected_fees) - [Function `burn_fee`](#@Specification_1_burn_fee) - [Function `mint_and_refund`](#@Specification_1_mint_and_refund) - - [Function `collect_fee`](#@Specification_1_collect_fee) - [Function `store_aptos_coin_burn_cap`](#@Specification_1_store_aptos_coin_burn_cap) - [Function `store_aptos_coin_mint_cap`](#@Specification_1_store_aptos_coin_mint_cap) - [Function `initialize_storage_refund`](#@Specification_1_initialize_storage_refund) @@ -53,7 +43,6 @@ This module provides an interface to burn or collect and redistribute transactio use 0x1::fungible_asset; use 0x1::option; use 0x1::signer; -use 0x1::stake; use 0x1::system_addresses;
@@ -151,7 +140,8 @@ Stores information about the block proposer and the amount of fees collected when executing the block. -
struct CollectedFeesPerBlock has key
+
#[deprecated]
+struct CollectedFeesPerBlock has key
 
@@ -308,47 +298,8 @@ Initializes the resource storing information about gas fees collection and distribution. Should be called by on-chain governance. -
public fun initialize_fee_collection_and_distribution(aptos_framework: &signer, burn_percentage: u8)
-
- - - -
-Implementation - - -
public fun initialize_fee_collection_and_distribution(aptos_framework: &signer, burn_percentage: u8) {
-    system_addresses::assert_aptos_framework(aptos_framework);
-    assert!(
-        !exists<CollectedFeesPerBlock>(@aptos_framework),
-        error::already_exists(EALREADY_COLLECTING_FEES)
-    );
-    assert!(burn_percentage <= 100, error::out_of_range(EINVALID_BURN_PERCENTAGE));
-
-    // Make sure stakng module is aware of transaction fees collection.
-    stake::initialize_validator_fees(aptos_framework);
-
-    // Initially, no fees are collected and the block proposer is not set.
-    let collected_fees = CollectedFeesPerBlock {
-        amount: coin::initialize_aggregatable_coin(aptos_framework),
-        proposer: option::none(),
-        burn_percentage,
-    };
-    move_to(aptos_framework, collected_fees);
-}
-
- - - -
- - - -## Function `is_fees_collection_enabled` - - - -
fun is_fees_collection_enabled(): bool
+
#[deprecated]
+public fun initialize_fee_collection_and_distribution(_aptos_framework: &signer, _burn_percentage: u8)
 
@@ -357,8 +308,8 @@ distribution. Should be called by on-chain governance. Implementation -
fun is_fees_collection_enabled(): bool {
-    exists<CollectedFeesPerBlock>(@aptos_framework)
+
public fun initialize_fee_collection_and_distribution(_aptos_framework: &signer, _burn_percentage: u8) {
+    abort error::not_implemented(ENO_LONGER_SUPPORTED)
 }
 
@@ -373,7 +324,7 @@ distribution. Should be called by on-chain governance. Sets the burn percentage for collected fees to a new value. Should be called by on-chain governance. -
public fun upgrade_burn_percentage(aptos_framework: &signer, new_burn_percentage: u8)
+
public fun upgrade_burn_percentage(_aptos_framework: &signer, _new_burn_percentage: u8)
 
@@ -383,158 +334,10 @@ Sets the burn percentage for collected fees to a new value. Should be called by
public fun upgrade_burn_percentage(
-    aptos_framework: &signer,
-    new_burn_percentage: u8
-) acquires AptosCoinCapabilities, CollectedFeesPerBlock {
-    system_addresses::assert_aptos_framework(aptos_framework);
-    assert!(new_burn_percentage <= 100, error::out_of_range(EINVALID_BURN_PERCENTAGE));
-
-    // Prior to upgrading the burn percentage, make sure to process collected
-    // fees. Otherwise we would use the new (incorrect) burn_percentage when
-    // processing fees later!
-    process_collected_fees();
-
-    if (is_fees_collection_enabled()) {
-        // Upgrade has no effect unless fees are being collected.
-        let burn_percentage = &mut borrow_global_mut<CollectedFeesPerBlock>(@aptos_framework).burn_percentage;
-        *burn_percentage = new_burn_percentage
-    }
-}
-
- - - - - - - -## Function `register_proposer_for_fee_collection` - -Registers the proposer of the block for gas fees collection. This function -can only be called at the beginning of the block. - - -
public(friend) fun register_proposer_for_fee_collection(proposer_addr: address)
-
- - - -
-Implementation - - -
public(friend) fun register_proposer_for_fee_collection(proposer_addr: address) acquires CollectedFeesPerBlock {
-    if (is_fees_collection_enabled()) {
-        let collected_fees = borrow_global_mut<CollectedFeesPerBlock>(@aptos_framework);
-        let _ = option::swap_or_fill(&mut collected_fees.proposer, proposer_addr);
-    }
-}
-
- - - -
- - - -## Function `burn_coin_fraction` - -Burns a specified fraction of the coin. - - -
fun burn_coin_fraction(coin: &mut coin::Coin<aptos_coin::AptosCoin>, burn_percentage: u8)
-
- - - -
-Implementation - - -
fun burn_coin_fraction(coin: &mut Coin<AptosCoin>, burn_percentage: u8) acquires AptosCoinCapabilities {
-    assert!(burn_percentage <= 100, error::out_of_range(EINVALID_BURN_PERCENTAGE));
-
-    let collected_amount = coin::value(coin);
-    spec {
-        // We assume that `burn_percentage * collected_amount` does not overflow.
-        assume burn_percentage * collected_amount <= MAX_U64;
-    };
-    let amount_to_burn = (burn_percentage as u64) * collected_amount / 100;
-    if (amount_to_burn > 0) {
-        let coin_to_burn = coin::extract(coin, amount_to_burn);
-        coin::burn(
-            coin_to_burn,
-            &borrow_global<AptosCoinCapabilities>(@aptos_framework).burn_cap,
-        );
-    }
-}
-
- - - -
- - - -## Function `process_collected_fees` - -Calculates the fee which should be distributed to the block proposer at the -end of an epoch, and records it in the system. This function can only be called -at the beginning of the block or during reconfiguration. - - -
public(friend) fun process_collected_fees()
-
- - - -
-Implementation - - -
public(friend) fun process_collected_fees() acquires AptosCoinCapabilities, CollectedFeesPerBlock {
-    if (!is_fees_collection_enabled()) {
-        return
-    };
-    let collected_fees = borrow_global_mut<CollectedFeesPerBlock>(@aptos_framework);
-
-    // If there are no collected fees, only unset the proposer. See the rationale for
-    // setting proposer to option::none() below.
-    if (coin::is_aggregatable_coin_zero(&collected_fees.amount)) {
-        if (option::is_some(&collected_fees.proposer)) {
-            let _ = option::extract(&mut collected_fees.proposer);
-        };
-        return
-    };
-
-    // Otherwise get the collected fee, and check if it can distributed later.
-    let coin = coin::drain_aggregatable_coin(&mut collected_fees.amount);
-    if (option::is_some(&collected_fees.proposer)) {
-        // Extract the address of proposer here and reset it to option::none(). This
-        // is particularly useful to avoid any undesired side-effects where coins are
-        // collected but never distributed or distributed to the wrong account.
-        // With this design, processing collected fees enforces that all fees will be burnt
-        // unless the proposer is specified in the block prologue. When we have a governance
-        // proposal that triggers reconfiguration, we distribute pending fees and burn the
-        // fee for the proposal. Otherwise, that fee would be leaked to the next block.
-        let proposer = option::extract(&mut collected_fees.proposer);
-
-        // Since the block can be produced by the VM itself, we have to make sure we catch
-        // this case.
-        if (proposer == @vm_reserved) {
-            burn_coin_fraction(&mut coin, 100);
-            coin::destroy_zero(coin);
-            return
-        };
-
-        burn_coin_fraction(&mut coin, collected_fees.burn_percentage);
-        stake::add_transaction_fee(proposer, coin);
-        return
-    };
-
-    // If checks did not pass, simply burn all collected coins and return none.
-    burn_coin_fraction(&mut coin, 100);
-    coin::destroy_zero(coin)
+    _aptos_framework: &signer,
+    _new_burn_percentage: u8
+) {
+    abort error::not_implemented(ENO_LONGER_SUPPORTED)
 }
 
@@ -608,37 +411,6 @@ Mint refund in epilogue. -
- - - -## Function `collect_fee` - -Collect transaction fees in epilogue. - - -
public(friend) fun collect_fee(account: address, fee: u64)
-
- - - -
-Implementation - - -
public(friend) fun collect_fee(account: address, fee: u64) acquires CollectedFeesPerBlock {
-    let collected_fees = borrow_global_mut<CollectedFeesPerBlock>(@aptos_framework);
-
-    // Here, we are always optimistic and always collect fees. If the proposer is not set,
-    // or we cannot redistribute fees later for some reason (e.g. account cannot receive AptoCoin)
-    // we burn them all at once. This way we avoid having a check for every transaction epilogue.
-    let collected_amount = &mut collected_fees.amount;
-    coin::collect_into_aggregatable_coin<AptosCoin>(account, fee, collected_amount);
-}
-
- - -
@@ -865,7 +637,8 @@ Only called during genesis. ### Resource `CollectedFeesPerBlock` -
struct CollectedFeesPerBlock has key
+
#[deprecated]
+struct CollectedFeesPerBlock has key
 
@@ -904,173 +677,13 @@ Only called during genesis. ### Function `initialize_fee_collection_and_distribution` -
public fun initialize_fee_collection_and_distribution(aptos_framework: &signer, burn_percentage: u8)
-
- - - - -
// This enforces high-level requirement 2:
-aborts_if exists<CollectedFeesPerBlock>(@aptos_framework);
-aborts_if burn_percentage > 100;
-let aptos_addr = signer::address_of(aptos_framework);
-// This enforces high-level requirement 3:
-aborts_if !system_addresses::is_aptos_framework_address(aptos_addr);
-aborts_if exists<ValidatorFees>(aptos_addr);
-include system_addresses::AbortsIfNotAptosFramework { account: aptos_framework };
-include aggregator_factory::CreateAggregatorInternalAbortsIf;
-aborts_if exists<CollectedFeesPerBlock>(aptos_addr);
-ensures exists<ValidatorFees>(aptos_addr);
-ensures exists<CollectedFeesPerBlock>(aptos_addr);
-
- - - - - -### Function `upgrade_burn_percentage` - - -
public fun upgrade_burn_percentage(aptos_framework: &signer, new_burn_percentage: u8)
-
- - - - -
aborts_if new_burn_percentage > 100;
-let aptos_addr = signer::address_of(aptos_framework);
-aborts_if !system_addresses::is_aptos_framework_address(aptos_addr);
-// This enforces high-level requirement 5 and high-level requirement 6:
-include ProcessCollectedFeesRequiresAndEnsures;
-ensures exists<CollectedFeesPerBlock>(@aptos_framework) ==>
-    global<CollectedFeesPerBlock>(@aptos_framework).burn_percentage == new_burn_percentage;
-
- - - - - -### Function `register_proposer_for_fee_collection` - - -
public(friend) fun register_proposer_for_fee_collection(proposer_addr: address)
-
- - - - -
aborts_if false;
-// This enforces high-level requirement 6:
-ensures is_fees_collection_enabled() ==>
-    option::spec_borrow(global<CollectedFeesPerBlock>(@aptos_framework).proposer) == proposer_addr;
-
- - - - - -### Function `burn_coin_fraction` - - -
fun burn_coin_fraction(coin: &mut coin::Coin<aptos_coin::AptosCoin>, burn_percentage: u8)
-
- - - - -
requires burn_percentage <= 100;
-requires exists<AptosCoinCapabilities>(@aptos_framework);
-requires exists<CoinInfo<AptosCoin>>(@aptos_framework);
-let amount_to_burn = (burn_percentage * coin::value(coin)) / 100;
-include amount_to_burn > 0 ==> coin::CoinSubAbortsIf<AptosCoin> { amount: amount_to_burn };
-ensures coin.value == old(coin).value - amount_to_burn;
-
- - - - - - - -
fun collectedFeesAggregator(): AggregatableCoin<AptosCoin> {
-   global<CollectedFeesPerBlock>(@aptos_framework).amount
-}
-
- - - - - - - -
schema RequiresCollectedFeesPerValueLeqBlockAptosSupply {
-    let maybe_supply = coin::get_coin_supply_opt<AptosCoin>();
-    requires
-        (is_fees_collection_enabled() && option::is_some(maybe_supply)) ==>
-            (aggregator::spec_aggregator_get_val(global<CollectedFeesPerBlock>(@aptos_framework).amount.value) <=
-                optional_aggregator::optional_aggregator_value(
-                    option::spec_borrow(coin::get_coin_supply_opt<AptosCoin>())
-                ));
-}
-
- - - - - - - -
schema ProcessCollectedFeesRequiresAndEnsures {
-    requires exists<AptosCoinCapabilities>(@aptos_framework);
-    requires exists<stake::ValidatorFees>(@aptos_framework);
-    requires exists<CoinInfo<AptosCoin>>(@aptos_framework);
-    include RequiresCollectedFeesPerValueLeqBlockAptosSupply;
-    aborts_if false;
-    let collected_fees = global<CollectedFeesPerBlock>(@aptos_framework);
-    let post post_collected_fees = global<CollectedFeesPerBlock>(@aptos_framework);
-    let pre_amount = aggregator::spec_aggregator_get_val(collected_fees.amount.value);
-    let post post_amount = aggregator::spec_aggregator_get_val(post_collected_fees.amount.value);
-    let fees_table = global<stake::ValidatorFees>(@aptos_framework).fees_table;
-    let post post_fees_table = global<stake::ValidatorFees>(@aptos_framework).fees_table;
-    let proposer = option::spec_borrow(collected_fees.proposer);
-    let fee_to_add = pre_amount - pre_amount * collected_fees.burn_percentage / 100;
-    ensures is_fees_collection_enabled() ==> option::spec_is_none(post_collected_fees.proposer) && post_amount == 0;
-    ensures is_fees_collection_enabled() && aggregator::spec_read(collected_fees.amount.value) > 0 &&
-        option::spec_is_some(collected_fees.proposer) ==>
-        if (proposer != @vm_reserved) {
-            if (table::spec_contains(fees_table, proposer)) {
-                table::spec_get(post_fees_table, proposer).value == table::spec_get(
-                    fees_table,
-                    proposer
-                ).value + fee_to_add
-            } else {
-                table::spec_get(post_fees_table, proposer).value == fee_to_add
-            }
-        } else {
-            option::spec_is_none(post_collected_fees.proposer) && post_amount == 0
-        };
-}
-
- - - - - -### Function `process_collected_fees` - - -
public(friend) fun process_collected_fees()
+
#[deprecated]
+public fun initialize_fee_collection_and_distribution(_aptos_framework: &signer, _burn_percentage: u8)
 
-
// This enforces high-level requirement 6:
-include ProcessCollectedFeesRequiresAndEnsures;
-
- - - ### Function `burn_fee` @@ -1136,38 +749,6 @@ Only called during genesis. - - -### Function `collect_fee` - - -
public(friend) fun collect_fee(account: address, fee: u64)
-
- - - - -
pragma verify = false;
-let collected_fees = global<CollectedFeesPerBlock>(@aptos_framework).amount;
-let aggr = collected_fees.value;
-let coin_store = global<coin::CoinStore<AptosCoin>>(account);
-aborts_if !exists<CollectedFeesPerBlock>(@aptos_framework);
-aborts_if fee > 0 && !exists<coin::CoinStore<AptosCoin>>(account);
-aborts_if fee > 0 && coin_store.coin.value < fee;
-aborts_if fee > 0 && aggregator::spec_aggregator_get_val(aggr)
-    + fee > aggregator::spec_get_limit(aggr);
-aborts_if fee > 0 && aggregator::spec_aggregator_get_val(aggr)
-    + fee > MAX_U128;
-let post post_coin_store = global<coin::CoinStore<AptosCoin>>(account);
-let post post_collected_fees = global<CollectedFeesPerBlock>(@aptos_framework).amount;
-ensures post_coin_store.coin.value == coin_store.coin.value - fee;
-ensures aggregator::spec_aggregator_get_val(post_collected_fees.value) == aggregator::spec_aggregator_get_val(
-    aggr
-) + fee;
-
- - - ### Function `store_aptos_coin_burn_cap` diff --git a/aptos-move/framework/aptos-framework/doc/transaction_validation.md b/aptos-move/framework/aptos-framework/doc/transaction_validation.md index b21495159a7c36..c126406ef89b5d 100644 --- a/aptos-move/framework/aptos-framework/doc/transaction_validation.md +++ b/aptos-move/framework/aptos-framework/doc/transaction_validation.md @@ -888,26 +888,11 @@ Called by the Adapter ); }; - let amount_to_burn = if (features::collect_and_distribute_gas_fees()) { - // TODO(gas): We might want to distinguish the refundable part of the charge and burn it or track - // it separately, so that we don't increase the total supply by refunding. - - // If transaction fees are redistributed to validators, collect them here for - // later redistribution. - transaction_fee::collect_fee(gas_payer, transaction_fee_amount); - 0 - } else { - // Otherwise, just burn the fee. - // TODO: this branch should be removed completely when transaction fee collection - // is tested and is fully proven to work well. - transaction_fee_amount - }; - - if (amount_to_burn > storage_fee_refunded) { - let burn_amount = amount_to_burn - storage_fee_refunded; + if (transaction_fee_amount > storage_fee_refunded) { + let burn_amount = transaction_fee_amount - storage_fee_refunded; transaction_fee::burn_fee(gas_payer, burn_amount); - } else if (amount_to_burn < storage_fee_refunded) { - let mint_amount = storage_fee_refunded - amount_to_burn; + } else if (transaction_fee_amount < storage_fee_refunded) { + let mint_amount = storage_fee_refunded - transaction_fee_amount; transaction_fee::mint_and_refund(gas_payer, mint_amount) }; }; @@ -1372,19 +1357,7 @@ Skip transaction_fee::burn_fee verification. aborts_if !exists<Account>(addr); aborts_if !(global<Account>(addr).sequence_number < MAX_U64); ensures account.sequence_number == pre_account.sequence_number + 1; - let collect_fee_enabled = features::spec_is_enabled(features::COLLECT_AND_DISTRIBUTE_GAS_FEES); - let collected_fees = global<CollectedFeesPerBlock>(@aptos_framework).amount; - let aggr = collected_fees.value; - let aggr_val = aggregator::spec_aggregator_get_val(aggr); - let aggr_lim = aggregator::spec_get_limit(aggr); - // This enforces high-level requirement 3: - aborts_if collect_fee_enabled && !exists<CollectedFeesPerBlock>(@aptos_framework); - aborts_if collect_fee_enabled && transaction_fee_amount > 0 && aggr_val + transaction_fee_amount > aggr_lim; - let amount_to_burn = if (collect_fee_enabled) { - 0 - } else { - transaction_fee_amount - storage_fee_refunded - }; + let amount_to_burn = transaction_fee_amount - storage_fee_refunded; let apt_addr = type_info::type_of<AptosCoin>().account_address; let maybe_apt_supply = global<CoinInfo<AptosCoin>>(apt_addr).supply; let total_supply_enabled = option::spec_is_some(maybe_apt_supply); @@ -1397,11 +1370,7 @@ Skip transaction_fee::burn_fee verification. aborts_if amount_to_burn > 0 && !exists<CoinInfo<AptosCoin>>(apt_addr); aborts_if amount_to_burn > 0 && total_supply_enabled && apt_supply_value < amount_to_burn; ensures total_supply_enabled ==> apt_supply_value - amount_to_burn == post_apt_supply_value; - let amount_to_mint = if (collect_fee_enabled) { - storage_fee_refunded - } else { - storage_fee_refunded - transaction_fee_amount - }; + let amount_to_mint = storage_fee_refunded - transaction_fee_amount; let total_supply = coin::supply<AptosCoin>; let post post_total_supply = coin::supply<AptosCoin>; aborts_if amount_to_mint > 0 && !exists<CoinStore<AptosCoin>>(addr); diff --git a/aptos-move/framework/aptos-framework/doc/version.md b/aptos-move/framework/aptos-framework/doc/version.md index c201f455c86f14..e67b4a48b17b42 100644 --- a/aptos-move/framework/aptos-framework/doc/version.md +++ b/aptos-move/framework/aptos-framework/doc/version.md @@ -358,7 +358,6 @@ Abort if resource already exists in @aptos_framwork when initializi
pragma verify_duration_estimate = 120;
-include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply;
 include staking_config::StakingRewardsConfigRequirement;
 requires chain_status::is_genesis();
 requires timestamp::spec_now_microseconds() >= reconfiguration::last_reconfiguration_time();
diff --git a/aptos-move/framework/aptos-framework/sources/aptos_governance.spec.move b/aptos-move/framework/aptos-framework/sources/aptos_governance.spec.move
index 4c0189023816ca..de0e3940b31472 100644
--- a/aptos-move/framework/aptos-framework/sources/aptos_governance.spec.move
+++ b/aptos-move/framework/aptos-framework/sources/aptos_governance.spec.move
@@ -138,7 +138,6 @@ spec aptos_framework::aptos_governance {
         use aptos_framework::chain_status;
         use aptos_framework::coin::CoinInfo;
         use aptos_framework::aptos_coin::AptosCoin;
-        use aptos_framework::transaction_fee;
         pragma verify = false; // TODO: set because of timeout (property proved).
         let addr = signer::address_of(aptos_framework);
         aborts_if addr != @aptos_framework;
@@ -146,7 +145,6 @@ spec aptos_framework::aptos_governance {
             framework: aptos_framework
         };
         include stake::GetReconfigStartTimeRequirement;
-        include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply;
         requires chain_status::is_operating();
         requires exists(@aptos_framework);
         requires exists>(@aptos_framework);
@@ -578,7 +576,6 @@ spec aptos_framework::aptos_governance {
         use aptos_framework::chain_status;
         use aptos_framework::coin::CoinInfo;
         use aptos_framework::aptos_coin::AptosCoin;
-        use aptos_framework::transaction_fee;
         pragma verify = false; // TODO: set because of timeout (property proved).
         aborts_if !system_addresses::is_aptos_framework_address(signer::address_of(aptos_framework));
         include reconfiguration_with_dkg::FinishRequirement {
@@ -586,7 +583,6 @@ spec aptos_framework::aptos_governance {
         };
         include stake::GetReconfigStartTimeRequirement;
 
-        include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply;
         requires chain_status::is_operating();
         requires exists(@aptos_framework);
         requires exists>(@aptos_framework);
diff --git a/aptos-move/framework/aptos-framework/sources/block.move b/aptos-move/framework/aptos-framework/sources/block.move
index 5899481316be70..0b8f96a5a1079b 100644
--- a/aptos-move/framework/aptos-framework/sources/block.move
+++ b/aptos-move/framework/aptos-framework/sources/block.move
@@ -1,7 +1,6 @@
 /// This module defines a struct storing the metadata of the block and new block events.
 module aptos_framework::block {
     use std::error;
-    use std::features;
     use std::vector;
     use std::option;
     use aptos_std::table_with_length::{Self, TableWithLength};
@@ -16,7 +15,6 @@ module aptos_framework::block {
     use aptos_framework::state_storage;
     use aptos_framework::system_addresses;
     use aptos_framework::timestamp;
-    use aptos_framework::transaction_fee;
 
     friend aptos_framework::genesis;
 
@@ -202,15 +200,6 @@ module aptos_framework::block {
         };
         emit_new_block_event(vm, &mut block_metadata_ref.new_block_events, new_block_event, new_block_event_v2);
 
-        if (features::collect_and_distribute_gas_fees()) {
-            // Assign the fees collected from the previous block to the previous block proposer.
-            // If for any reason the fees cannot be assigned, this function burns the collected coins.
-            transaction_fee::process_collected_fees();
-            // Set the proposer of this block as the receiver of the fees, so that the fees for this
-            // block are assigned to the right account.
-            transaction_fee::register_proposer_for_fee_collection(proposer);
-        };
-
         // Performance scores have to be updated before the epoch transition as the transaction that triggers the
         // transition is the last block in the previous epoch.
         stake::update_performance_statistics(proposer_index, failed_proposer_indices);
diff --git a/aptos-move/framework/aptos-framework/sources/block.spec.move b/aptos-move/framework/aptos-framework/sources/block.spec.move
index 2a8d982bd8ed7c..ca6f9628db2afd 100644
--- a/aptos-move/framework/aptos-framework/sources/block.spec.move
+++ b/aptos-move/framework/aptos-framework/sources/block.spec.move
@@ -127,7 +127,6 @@ spec aptos_framework::block {
         use aptos_framework::chain_status;
         use aptos_framework::coin::CoinInfo;
         use aptos_framework::aptos_coin::AptosCoin;
-        use aptos_framework::transaction_fee;
         use aptos_framework::staking_config;
 
         vm: signer;
@@ -147,7 +146,6 @@ spec aptos_framework::block {
         requires (proposer != @vm_reserved) ==> (timestamp::spec_now_microseconds() < timestamp);
         requires exists(@aptos_framework);
         requires exists>(@aptos_framework);
-        include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply;
         include staking_config::StakingRewardsConfigRequirement;
     }
 
diff --git a/aptos-move/framework/aptos-framework/sources/coin.move b/aptos-move/framework/aptos-framework/sources/coin.move
index 91a54edb7fdddb..88c62c9a53b7d1 100644
--- a/aptos-move/framework/aptos-framework/sources/coin.move
+++ b/aptos-move/framework/aptos-framework/sources/coin.move
@@ -9,7 +9,7 @@ module aptos_framework::coin {
 
     use aptos_framework::account;
     use aptos_framework::aggregator_factory;
-    use aptos_framework::aggregator::{Self, Aggregator};
+    use aptos_framework::aggregator::Aggregator;
     use aptos_framework::event::{Self, EventHandle};
     use aptos_framework::guid;
     use aptos_framework::optional_aggregator::{Self, OptionalAggregator};
@@ -122,9 +122,8 @@ module aptos_framework::coin {
         value: u64,
     }
 
-    /// Represents a coin with aggregator as its value. This allows to update
-    /// the coin in every transaction avoiding read-modify-write conflicts. Only
-    /// used for gas fees distribution by Aptos Framework (0x1).
+    #[deprecated]
+    /// DEPRECATED
     struct AggregatableCoin has store {
         /// Amount of aggregatable coin this address has.
         value: Aggregator,
@@ -556,93 +555,6 @@ module aptos_framework::coin {
         *allow_upgrades = allowed;
     }
 
-    //
-    //  Aggregatable coin functions
-    //
-
-    /// Creates a new aggregatable coin with value overflowing on `limit`. Note that this function can
-    /// only be called by Aptos Framework (0x1) account for now because of `create_aggregator`.
-    public(friend) fun initialize_aggregatable_coin(aptos_framework: &signer): AggregatableCoin {
-        let aggregator = aggregator_factory::create_aggregator(aptos_framework, MAX_U64);
-        AggregatableCoin {
-            value: aggregator,
-        }
-    }
-
-    /// Returns true if the value of aggregatable coin is zero.
-    public(friend) fun is_aggregatable_coin_zero(coin: &AggregatableCoin): bool {
-        let amount = aggregator::read(&coin.value);
-        amount == 0
-    }
-
-    /// Drains the aggregatable coin, setting it to zero and returning a standard coin.
-    public(friend) fun drain_aggregatable_coin(coin: &mut AggregatableCoin): Coin {
-        spec {
-            // TODO: The data invariant is not properly assumed from CollectedFeesPerBlock.
-            assume aggregator::spec_get_limit(coin.value) == MAX_U64;
-        };
-        let amount = aggregator::read(&coin.value);
-        assert!(amount <= MAX_U64, error::out_of_range(EAGGREGATABLE_COIN_VALUE_TOO_LARGE));
-        spec {
-            update aggregate_supply = aggregate_supply - amount;
-        };
-        aggregator::sub(&mut coin.value, amount);
-        spec {
-            update supply = supply + amount;
-        };
-        Coin {
-            value: (amount as u64),
-        }
-    }
-
-    /// Merges `coin` into aggregatable coin (`dst_coin`).
-    public(friend) fun merge_aggregatable_coin(
-        dst_coin: &mut AggregatableCoin,
-        coin: Coin
-    ) {
-        spec {
-            update supply = supply - coin.value;
-        };
-        let Coin { value } = coin;
-        let amount = (value as u128);
-        spec {
-            update aggregate_supply = aggregate_supply + amount;
-        };
-        aggregator::add(&mut dst_coin.value, amount);
-    }
-
-    /// Collects a specified amount of coin form an account into aggregatable coin.
-    public(friend) fun collect_into_aggregatable_coin(
-        account_addr: address,
-        amount: u64,
-        dst_coin: &mut AggregatableCoin,
-    ) acquires CoinStore, CoinConversionMap, CoinInfo, PairedCoinType {
-        // Skip collecting if amount is zero.
-        if (amount == 0) {
-            return
-        };
-
-        let (coin_amount_to_collect, fa_amount_to_collect) = calculate_amount_to_withdraw(
-            account_addr,
-            amount
-        );
-        let coin = if (coin_amount_to_collect > 0) {
-            let coin_store = borrow_global_mut>(account_addr);
-            extract(&mut coin_store.coin, coin_amount_to_collect)
-        } else {
-            zero()
-        };
-        if (fa_amount_to_collect > 0) {
-            let store_addr = primary_fungible_store::primary_store_address(
-                account_addr,
-                option::destroy_some(paired_metadata())
-            );
-            let fa = fungible_asset::withdraw_internal(store_addr, fa_amount_to_collect);
-            merge(&mut coin, fungible_asset_to_coin(fa));
-        };
-        merge_aggregatable_coin(dst_coin, coin);
-    }
-
     inline fun calculate_amount_to_withdraw(
         account_addr: address,
         amount: u64
@@ -1841,51 +1753,6 @@ module aptos_framework::coin {
         aggregator::destroy(value);
     }
 
-    #[test(framework = @aptos_framework)]
-    public entry fun test_collect_from_and_drain(
-        framework: signer,
-    ) acquires CoinInfo, CoinStore, CoinConversionMap, PairedCoinType {
-        let framework_addr = signer::address_of(&framework);
-        account::create_account_for_test(framework_addr);
-        let (burn_cap, freeze_cap, mint_cap) = initialize_and_register_fake_money(&framework, 1, true);
-
-        // Collect from coin store only.
-        let coins_minted = mint(100, &mint_cap);
-        deposit(framework_addr, coins_minted);
-        let aggregatable_coin = initialize_aggregatable_coin(&framework);
-        collect_into_aggregatable_coin(framework_addr, 50, &mut aggregatable_coin);
-
-        let fa_minted = coin_to_fungible_asset(mint(100, &mint_cap));
-        primary_fungible_store::deposit(framework_addr, fa_minted);
-        assert!(balance(framework_addr) == 150, 0);
-        assert!(*option::borrow(&supply()) == 200, 0);
-
-        // Collect from coin store and fungible store.
-        collect_into_aggregatable_coin(framework_addr, 100, &mut aggregatable_coin);
-
-        assert!(balance(framework_addr) == 50, 0);
-        maybe_convert_to_fungible_store(framework_addr);
-        // Collect from fungible store only.
-        collect_into_aggregatable_coin(framework_addr, 30, &mut aggregatable_coin);
-
-        // Check that aggregatable coin has the right amount.
-        let collected_coin = drain_aggregatable_coin(&mut aggregatable_coin);
-        assert!(is_aggregatable_coin_zero(&aggregatable_coin), 0);
-        assert!(value(&collected_coin) == 180, 0);
-
-        // Supply of coins should be unchanged, but the balance on the account should decrease.
-        assert!(balance(framework_addr) == 20, 0);
-        assert!(*option::borrow(&supply()) == 200, 0);
-
-        burn(collected_coin, &burn_cap);
-        destroy_aggregatable_coin_for_test(aggregatable_coin);
-        move_to(&framework, FakeMoneyCapabilities {
-            burn_cap,
-            freeze_cap,
-            mint_cap,
-        });
-    }
-
     #[test_only]
     fun deposit_to_coin_store(account_addr: address, coin: Coin) acquires CoinStore {
         assert!(
diff --git a/aptos-move/framework/aptos-framework/sources/coin.spec.move b/aptos-move/framework/aptos-framework/sources/coin.spec.move
index 2564bc0daa8c67..32bdc6645b3ded 100644
--- a/aptos-move/framework/aptos-framework/sources/coin.spec.move
+++ b/aptos-move/framework/aptos-framework/sources/coin.spec.move
@@ -578,46 +578,4 @@ spec aptos_framework::coin {
         aborts_if coin_store.frozen;
         aborts_if balance < amount;
     }
-
-    spec initialize_aggregatable_coin(aptos_framework: &signer): AggregatableCoin {
-        include system_addresses::AbortsIfNotAptosFramework { account: aptos_framework };
-        include aggregator_factory::CreateAggregatorInternalAbortsIf;
-    }
-
-    spec is_aggregatable_coin_zero(coin: &AggregatableCoin): bool {
-        aborts_if false;
-        ensures result == (aggregator::spec_read(coin.value) == 0);
-    }
-
-    spec drain_aggregatable_coin(coin: &mut AggregatableCoin): Coin {
-        aborts_if aggregator::spec_read(coin.value) > MAX_U64;
-        ensures result.value == aggregator::spec_aggregator_get_val(old(coin).value);
-    }
-
-    spec merge_aggregatable_coin(dst_coin: &mut AggregatableCoin, coin: Coin) {
-        let aggr = dst_coin.value;
-        let post p_aggr = dst_coin.value;
-        aborts_if aggregator::spec_aggregator_get_val(aggr)
-            + coin.value > aggregator::spec_get_limit(aggr);
-        aborts_if aggregator::spec_aggregator_get_val(aggr)
-            + coin.value > MAX_U128;
-        ensures aggregator::spec_aggregator_get_val(aggr) + coin.value == aggregator::spec_aggregator_get_val(p_aggr);
-    }
-
-    spec collect_into_aggregatable_coin(account_addr: address, amount: u64, dst_coin: &mut AggregatableCoin) {
-        // TODO(fa_migration)
-        pragma verify = false;
-        let aggr = dst_coin.value;
-        let post p_aggr = dst_coin.value;
-        let coin_store = global>(account_addr);
-        let post p_coin_store = global>(account_addr);
-        aborts_if amount > 0 && !exists>(account_addr);
-        aborts_if amount > 0 && coin_store.coin.value < amount;
-        aborts_if amount > 0 && aggregator::spec_aggregator_get_val(aggr)
-            + amount > aggregator::spec_get_limit(aggr);
-        aborts_if amount > 0 && aggregator::spec_aggregator_get_val(aggr)
-            + amount > MAX_U128;
-        ensures aggregator::spec_aggregator_get_val(aggr) + amount == aggregator::spec_aggregator_get_val(p_aggr);
-        ensures coin_store.coin.value - amount == p_coin_store.coin.value;
-    }
 }
diff --git a/aptos-move/framework/aptos-framework/sources/configs/consensus_config.spec.move b/aptos-move/framework/aptos-framework/sources/configs/consensus_config.spec.move
index f0360989f47a67..5a19f6621ea86c 100644
--- a/aptos-move/framework/aptos-framework/sources/configs/consensus_config.spec.move
+++ b/aptos-move/framework/aptos-framework/sources/configs/consensus_config.spec.move
@@ -50,12 +50,10 @@ spec aptos_framework::consensus_config {
         use aptos_framework::stake;
         use aptos_framework::coin::CoinInfo;
         use aptos_framework::aptos_coin::AptosCoin;
-        use aptos_framework::transaction_fee;
         use aptos_framework::staking_config;
 
         // TODO: set because of timeout (property proved)
         pragma verify_duration_estimate = 600;
-        include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply;
         include staking_config::StakingRewardsConfigRequirement;
         let addr = signer::address_of(account);
         /// [high-level-req-2]
diff --git a/aptos-move/framework/aptos-framework/sources/configs/execution_config.spec.move b/aptos-move/framework/aptos-framework/sources/configs/execution_config.spec.move
index 4b04d757f2fdbe..9573dacc93fc75 100644
--- a/aptos-move/framework/aptos-framework/sources/configs/execution_config.spec.move
+++ b/aptos-move/framework/aptos-framework/sources/configs/execution_config.spec.move
@@ -10,7 +10,6 @@ spec aptos_framework::execution_config {
         use aptos_framework::timestamp;
         use std::signer;
         use std::features;
-        use aptos_framework::transaction_fee;
         use aptos_framework::chain_status;
         use aptos_framework::stake;
         use aptos_framework::staking_config;
@@ -19,7 +18,6 @@ spec aptos_framework::execution_config {
         // TODO: set because of timeout (property proved)
         pragma verify_duration_estimate = 600;
         let addr = signer::address_of(account);
-        include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply;
         requires chain_status::is_genesis();
         requires exists(@aptos_framework);
         requires exists(@aptos_framework);
diff --git a/aptos-move/framework/aptos-framework/sources/configs/gas_schedule.spec.move b/aptos-move/framework/aptos-framework/sources/configs/gas_schedule.spec.move
index 7ce238f7b9959e..725ab297928e9d 100644
--- a/aptos-move/framework/aptos-framework/sources/configs/gas_schedule.spec.move
+++ b/aptos-move/framework/aptos-framework/sources/configs/gas_schedule.spec.move
@@ -52,7 +52,6 @@ spec aptos_framework::gas_schedule {
         use aptos_framework::stake;
         use aptos_framework::coin::CoinInfo;
         use aptos_framework::aptos_coin::AptosCoin;
-        use aptos_framework::transaction_fee;
         use aptos_framework::staking_config;
         use aptos_framework::chain_status;
 
@@ -61,7 +60,6 @@ spec aptos_framework::gas_schedule {
         requires exists(@aptos_framework);
         requires exists>(@aptos_framework);
         requires chain_status::is_genesis();
-        include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply;
         include staking_config::StakingRewardsConfigRequirement;
 
         /// [high-level-req-2]
@@ -80,7 +78,6 @@ spec aptos_framework::gas_schedule {
         use aptos_framework::stake;
         use aptos_framework::coin::CoinInfo;
         use aptos_framework::aptos_coin::AptosCoin;
-        use aptos_framework::transaction_fee;
         use aptos_framework::staking_config;
 
         // TODO: set because of timeout (property proved).
@@ -88,7 +85,6 @@ spec aptos_framework::gas_schedule {
         requires exists(@aptos_framework);
         requires exists>(@aptos_framework);
         include system_addresses::AbortsIfNotAptosFramework{ account: aptos_framework };
-        include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply;
         include staking_config::StakingRewardsConfigRequirement;
         aborts_if !exists(@aptos_framework);
         ensures global(@aptos_framework) == config;
diff --git a/aptos-move/framework/aptos-framework/sources/configs/version.spec.move b/aptos-move/framework/aptos-framework/sources/configs/version.spec.move
index 5ce2685d1158b6..5c41faa7a451f2 100644
--- a/aptos-move/framework/aptos-framework/sources/configs/version.spec.move
+++ b/aptos-move/framework/aptos-framework/sources/configs/version.spec.move
@@ -29,13 +29,11 @@ spec aptos_framework::version {
         use aptos_framework::stake;
         use aptos_framework::coin::CoinInfo;
         use aptos_framework::aptos_coin::AptosCoin;
-        use aptos_framework::transaction_fee;
         use aptos_framework::staking_config;
         use aptos_framework::reconfiguration;
 
         // TODO: set because of timeout (property proved)
         pragma verify_duration_estimate = 120;
-        include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply;
         include staking_config::StakingRewardsConfigRequirement;
         requires chain_status::is_genesis();
         requires timestamp::spec_now_microseconds() >= reconfiguration::last_reconfiguration_time();
diff --git a/aptos-move/framework/aptos-framework/sources/genesis.spec.move b/aptos-move/framework/aptos-framework/sources/genesis.spec.move
index 439d72c81b43ce..8378b5b4cfafef 100644
--- a/aptos-move/framework/aptos-framework/sources/genesis.spec.move
+++ b/aptos-move/framework/aptos-framework/sources/genesis.spec.move
@@ -157,10 +157,8 @@ spec aptos_framework::genesis {
         requires chain_status::is_operating();
         requires len(execution_config) > 0;
         requires exists(@aptos_framework);
-        requires exists(@aptos_framework);
         requires exists>(@aptos_framework);
         include CompareTimeRequires;
-        include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply;
     }
 
     spec schema CompareTimeRequires {
diff --git a/aptos-move/framework/aptos-framework/sources/reconfiguration.move b/aptos-move/framework/aptos-framework/sources/reconfiguration.move
index 04a48b6466e754..6bf02a1d1b0f5a 100644
--- a/aptos-move/framework/aptos-framework/sources/reconfiguration.move
+++ b/aptos-move/framework/aptos-framework/sources/reconfiguration.move
@@ -13,7 +13,6 @@ module aptos_framework::reconfiguration {
     use aptos_framework::chain_status;
     use aptos_framework::reconfiguration_state;
     use aptos_framework::storage_gas;
-    use aptos_framework::transaction_fee;
 
     friend aptos_framework::aptos_governance;
     friend aptos_framework::block;
@@ -131,20 +130,6 @@ module aptos_framework::reconfiguration {
 
         reconfiguration_state::on_reconfig_start();
 
-        // Reconfiguration "forces the block" to end, as mentioned above. Therefore, we must process the collected fees
-        // explicitly so that staking can distribute them.
-        //
-        // This also handles the case when a validator is removed due to the governance proposal. In particular, removing
-        // the validator causes a reconfiguration. We explicitly process fees, i.e. we drain aggregatable coin and populate
-        // the fees table, prior to calling `on_new_epoch()`. That call, in turn, distributes transaction fees for all active
-        // and pending_inactive validators, which include any validator that is to be removed.
-        if (features::collect_and_distribute_gas_fees()) {
-            // All transactions after reconfiguration are Retry. Therefore, when the next
-            // block starts and tries to assign/burn collected fees it will be just 0 and
-            // nothing will be assigned.
-            transaction_fee::process_collected_fees();
-        };
-
         // Call stake to compute the new validator set and distribute rewards and transaction fees.
         stake::on_new_epoch();
         storage_gas::on_reconfig();
diff --git a/aptos-move/framework/aptos-framework/sources/reconfiguration.spec.move b/aptos-move/framework/aptos-framework/sources/reconfiguration.spec.move
index 4bea1460fdb548..d15574105efc5d 100644
--- a/aptos-move/framework/aptos-framework/sources/reconfiguration.spec.move
+++ b/aptos-move/framework/aptos-framework/sources/reconfiguration.spec.move
@@ -127,7 +127,6 @@ spec aptos_framework::reconfiguration {
 
     spec reconfigure {
         use aptos_framework::aptos_coin;
-        use aptos_framework::transaction_fee;
         use aptos_framework::staking_config;
 
         // TODO: set because of timeout (property proved)
@@ -139,7 +138,6 @@ spec aptos_framework::reconfiguration {
             && timestamp::spec_now_microseconds() != global(@aptos_framework).last_reconfiguration_time;
         include features::spec_periodical_reward_rate_decrease_enabled() ==> staking_config::StakingRewardsConfigEnabledRequirement;
         include success ==> aptos_coin::ExistsAptosCoin;
-        include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply;
         aborts_if false;
         // The ensure conditions of the reconfigure function are not fully written, because there is a new cycle in it,
         // but its existing ensure conditions satisfy hp.
diff --git a/aptos-move/framework/aptos-framework/sources/reconfiguration_with_dkg.spec.move b/aptos-move/framework/aptos-framework/sources/reconfiguration_with_dkg.spec.move
index cddde359d5a9fa..bf6462deaf55b3 100644
--- a/aptos-move/framework/aptos-framework/sources/reconfiguration_with_dkg.spec.move
+++ b/aptos-move/framework/aptos-framework/sources/reconfiguration_with_dkg.spec.move
@@ -31,7 +31,6 @@ spec aptos_framework::reconfiguration_with_dkg {
         use aptos_framework::stake;
         use aptos_framework::coin::CoinInfo;
         use aptos_framework::aptos_coin::AptosCoin;
-        use aptos_framework::transaction_fee;
         use aptos_framework::staking_config;
         use aptos_framework::config_buffer;
         use aptos_framework::version;
@@ -47,7 +46,6 @@ spec aptos_framework::reconfiguration_with_dkg {
         requires exists>(@aptos_framework);
         include staking_config::StakingRewardsConfigRequirement;
         requires exists(@aptos_framework);
-        include transaction_fee::RequiresCollectedFeesPerValueLeqBlockAptosSupply;
         requires exists(@std);
         include config_buffer::OnNewEpochRequirement;
         include config_buffer::OnNewEpochRequirement;
diff --git a/aptos-move/framework/aptos-framework/sources/stake.move b/aptos-move/framework/aptos-framework/sources/stake.move
index 9639ffa8ff07d2..59158dd64fe66a 100644
--- a/aptos-move/framework/aptos-framework/sources/stake.move
+++ b/aptos-move/framework/aptos-framework/sources/stake.move
@@ -25,7 +25,7 @@ module aptos_framework::stake {
     use std::vector;
     use aptos_std::bls12381;
     use aptos_std::math64::min;
-    use aptos_std::table::{Self, Table};
+    use aptos_std::table::Table;
     use aptos_framework::aptos_coin::AptosCoin;
     use aptos_framework::account;
     use aptos_framework::coin::{Self, Coin, MintCapability};
@@ -338,34 +338,12 @@ module aptos_framework::stake {
         pool_address: address,
     }
 
-    /// Stores transaction fees assigned to validators. All fees are distributed to validators
-    /// at the end of the epoch.
+    #[deprecated]
+    /// DEPRECATED
     struct ValidatorFees has key {
         fees_table: Table>,
     }
 
-    /// Initializes the resource storing information about collected transaction fees per validator.
-    /// Used by `transaction_fee.move` to initialize fee collection and distribution.
-    public(friend) fun initialize_validator_fees(aptos_framework: &signer) {
-        system_addresses::assert_aptos_framework(aptos_framework);
-        assert!(
-            !exists(@aptos_framework),
-            error::already_exists(EFEES_TABLE_ALREADY_EXISTS)
-        );
-        move_to(aptos_framework, ValidatorFees { fees_table: table::new() });
-    }
-
-    /// Stores the transaction fee collected to the specified validator address.
-    public(friend) fun add_transaction_fee(validator_addr: address, fee: Coin) acquires ValidatorFees {
-        let fees_table = &mut borrow_global_mut(@aptos_framework).fees_table;
-        if (table::contains(fees_table, validator_addr)) {
-            let collected_fee = table::borrow_mut(fees_table, validator_addr);
-            coin::merge(collected_fee, fee);
-        } else {
-            table::add(fees_table, validator_addr, fee);
-        }
-    }
-
     #[view]
     /// Return the lockup expiration of the stake pool at `pool_address`.
     /// This will throw an error if there's no stake pool at `pool_address`.
@@ -1232,7 +1210,7 @@ module aptos_framework::stake {
     /// 4. The validator's voting power in the validator set is updated to be the corresponding staking pool's voting
     /// power.
     public(friend) fun on_new_epoch(
-    ) acquires StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         let validator_set = borrow_global_mut(@aptos_framework);
         let config = staking_config::get();
         let validator_perf = borrow_global_mut(@aptos_framework);
@@ -1354,7 +1332,7 @@ module aptos_framework::stake {
     }
 
 
-    public fun next_validator_consensus_infos(): vector acquires ValidatorSet, ValidatorPerformance, StakePool, ValidatorFees, ValidatorConfig {
+    public fun next_validator_consensus_infos(): vector acquires ValidatorSet, ValidatorPerformance, StakePool, ValidatorConfig {
         // Init.
         let cur_validator_set = borrow_global(@aptos_framework);
         let staking_config = staking_config::get();
@@ -1409,25 +1387,16 @@ module aptos_framework::stake {
                 0
             };
 
-            let cur_fee = 0;
-            if (features::collect_and_distribute_gas_fees()) {
-                let fees_table = &borrow_global(@aptos_framework).fees_table;
-                if (table::contains(fees_table, candidate.addr)) {
-                    let fee_coin = table::borrow(fees_table, candidate.addr);
-                    cur_fee = coin::value(fee_coin);
-                }
-            };
-
             let lockup_expired = get_reconfig_start_time_secs() >= stake_pool.locked_until_secs;
             spec {
-                assume cur_active + cur_pending_active + cur_reward + cur_fee <= MAX_U64;
-                assume cur_active + cur_pending_inactive + cur_pending_active + cur_reward + cur_fee <= MAX_U64;
+                assume cur_active + cur_pending_active + cur_reward <= MAX_U64;
+                assume cur_active + cur_pending_inactive + cur_pending_active + cur_reward <= MAX_U64;
             };
             let new_voting_power =
                 cur_active
                 + if (lockup_expired) { 0 } else { cur_pending_inactive }
                 + cur_pending_active
-                + cur_reward + cur_fee;
+                + cur_reward;
 
             if (new_voting_power >= minimum_stake) {
                 let config = *borrow_global(candidate.addr);
@@ -1546,7 +1515,7 @@ module aptos_framework::stake {
         validator_perf: &ValidatorPerformance,
         pool_address: address,
         staking_config: &StakingConfig,
-    ) acquires StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorFees {
+    ) acquires StakePool, AptosCoinCapabilities, ValidatorConfig {
         let stake_pool = borrow_global_mut(pool_address);
         let validator_config = borrow_global(pool_address);
         let cur_validator_perf = vector::borrow(&validator_perf.validators, validator_config.validator_index);
@@ -1579,15 +1548,6 @@ module aptos_framework::stake {
         // Pending active stake can now be active.
         coin::merge(&mut stake_pool.active, coin::extract_all(&mut stake_pool.pending_active));
 
-        // Additionally, distribute transaction fees.
-        if (features::collect_and_distribute_gas_fees()) {
-            let fees_table = &mut borrow_global_mut(@aptos_framework).fees_table;
-            if (table::contains(fees_table, pool_address)) {
-                let coin = table::remove(fees_table, pool_address);
-                coin::merge(&mut stake_pool.active, coin);
-            };
-        };
-
         // Pending inactive stake is only fully unlocked and moved into inactive if the current lockup cycle has expired
         let current_lockup_expiration = stake_pool.locked_until_secs;
         if (get_reconfig_start_time_secs() >= current_lockup_expiration) {
@@ -1800,7 +1760,7 @@ module aptos_framework::stake {
         operator: &signer,
         pool_address: address,
         should_end_epoch: bool,
-    ) acquires AptosCoinCapabilities, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AptosCoinCapabilities, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         let pk_bytes = bls12381::public_key_to_bytes(pk);
         let pop_bytes = bls12381::proof_of_possession_to_bytes(pop);
         rotate_consensus_key(operator, pool_address, pk_bytes, pop_bytes);
@@ -1812,7 +1772,7 @@ module aptos_framework::stake {
 
     #[test_only]
     public fun fast_forward_to_unlock(pool_address: address)
-    acquires AptosCoinCapabilities, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    acquires AptosCoinCapabilities, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         let expiration_time = get_lockup_secs(pool_address);
         timestamp::update_global_time_for_test_secs(expiration_time);
         end_epoch();
@@ -1881,7 +1841,7 @@ module aptos_framework::stake {
         amount: u64,
         should_join_validator_set: bool,
         should_end_epoch: bool,
-    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         let validator_address = signer::address_of(validator);
         if (!account::exists_at(signer::address_of(validator))) {
             account::create_account_for_test(validator_address);
@@ -1977,7 +1937,7 @@ module aptos_framework::stake {
     public entry fun test_inactive_validator_can_add_stake_if_exceeding_max_allowed(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
         let (_sk, pk, pop) = generate_identity();
         initialize_test_validator(&pk, &pop, validator, 100, false, false);
@@ -1992,7 +1952,7 @@ module aptos_framework::stake {
         aptos_framework: &signer,
         validator_1: &signer,
         validator_2: &signer,
-    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test_custom(aptos_framework, 50, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 10, 100000);
         // Have one validator join the set to ensure the validator set is not empty when main validator joins.
         let (_sk_1, pk_1, pop_1) = generate_identity();
@@ -2011,7 +1971,7 @@ module aptos_framework::stake {
     public entry fun test_active_validator_cannot_add_stake_if_exceeding_max_allowed(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
         // Validator joins validator set and waits for epoch end so it's in the validator set.
         let (_sk, pk, pop) = generate_identity();
@@ -2026,7 +1986,7 @@ module aptos_framework::stake {
     public entry fun test_active_validator_with_pending_inactive_stake_cannot_add_stake_if_exceeding_max_allowed(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
         // Validator joins validator set and waits for epoch end so it's in the validator set.
         let (_sk, pk, pop) = generate_identity();
@@ -2046,7 +2006,7 @@ module aptos_framework::stake {
         aptos_framework: &signer,
         validator_1: &signer,
         validator_2: &signer,
-    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
         let (_sk_1, pk_1, pop_1) = generate_identity();
         let (_sk_2, pk_2, pop_2) = generate_identity();
@@ -2064,7 +2024,7 @@ module aptos_framework::stake {
     public entry fun test_end_to_end(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
         let (_sk, pk, pop) = generate_identity();
         initialize_test_validator(&pk, &pop, validator, 100, true, true);
@@ -2121,7 +2081,7 @@ module aptos_framework::stake {
     public entry fun test_inactive_validator_with_existing_lockup_join_validator_set(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
         let (_sk, pk, pop) = generate_identity();
         initialize_test_validator(&pk, &pop, validator, 100, false, false);
@@ -2147,7 +2107,7 @@ module aptos_framework::stake {
     public entry fun test_cannot_reduce_lockup(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
         let (_sk, pk, pop) = generate_identity();
         initialize_test_validator(&pk, &pop, validator, 100, false, false);
@@ -2166,7 +2126,7 @@ module aptos_framework::stake {
         aptos_framework: &signer,
         validator_1: &signer,
         validator_2: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         // Only 50% voting power increase is allowed in each epoch.
         initialize_for_test_custom(aptos_framework, 50, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 10, 50);
         let (_sk_1, pk_1, pop_1) = generate_identity();
@@ -2188,7 +2148,7 @@ module aptos_framework::stake {
         aptos_framework: &signer,
         validator_1: &signer,
         validator_2: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test_custom(aptos_framework, 50, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 10, 10000);
         // Need 1 validator to be in the active validator set so joining limit works.
         let (_sk_1, pk_1, pop_1) = generate_identity();
@@ -2210,7 +2170,7 @@ module aptos_framework::stake {
         aptos_framework: &signer,
         validator_1: &signer,
         validator_2: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         // 100% voting power increase is allowed in each epoch.
         initialize_for_test_custom(aptos_framework, 50, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 10, 100);
         // Need 1 validator to be in the active validator set so joining limit works.
@@ -2230,7 +2190,7 @@ module aptos_framework::stake {
     public entry fun test_pending_active_validator_leaves_validator_set(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
         // Validator joins but epoch hasn't ended, so the validator is still pending_active.
         let (_sk, pk, pop) = generate_identity();
@@ -2254,7 +2214,7 @@ module aptos_framework::stake {
     public entry fun test_active_validator_cannot_add_more_stake_than_limit_in_multiple_epochs(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         // Only 50% voting power increase is allowed in each epoch.
         initialize_for_test_custom(aptos_framework, 50, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 10, 50);
         // Add initial stake and join the validator set.
@@ -2276,7 +2236,7 @@ module aptos_framework::stake {
     public entry fun test_active_validator_cannot_add_more_stake_than_limit(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         // Only 50% voting power increase is allowed in each epoch.
         initialize_for_test_custom(aptos_framework, 50, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 10, 50);
         let (_sk, pk, pop) = generate_identity();
@@ -2290,7 +2250,7 @@ module aptos_framework::stake {
     public entry fun test_active_validator_unlock_partial_stake(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         // Reward rate = 10%.
         initialize_for_test_custom(aptos_framework, 50, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 10, 100);
         let (_sk, pk, pop) = generate_identity();
@@ -2316,7 +2276,7 @@ module aptos_framework::stake {
     public entry fun test_active_validator_can_withdraw_all_stake_and_rewards_at_once(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
         let (_sk, pk, pop) = generate_identity();
         initialize_test_validator(&pk, &pop, validator, 100, true, true);
@@ -2353,7 +2313,7 @@ module aptos_framework::stake {
     public entry fun test_active_validator_unlocking_more_than_available_stake_should_cap(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
         let (_sk, pk, pop) = generate_identity();
         initialize_test_validator(&pk, &pop, validator, 100, false, false);
@@ -2367,7 +2327,7 @@ module aptos_framework::stake {
     public entry fun test_active_validator_withdraw_should_cap_by_inactive_stake(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
         // Initial balance = 900 (idle) + 100 (staked) = 1000.
         let (_sk, pk, pop) = generate_identity();
@@ -2392,7 +2352,7 @@ module aptos_framework::stake {
     public entry fun test_active_validator_can_reactivate_pending_inactive_stake(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
         let (_sk, pk, pop) = generate_identity();
         initialize_test_validator(&pk, &pop, validator, 100, true, true);
@@ -2411,7 +2371,7 @@ module aptos_framework::stake {
     public entry fun test_active_validator_reactivate_more_than_available_pending_inactive_stake_should_cap(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
         let (_sk, pk, pop) = generate_identity();
         initialize_test_validator(&pk, &pop, validator, 100, true, true);
@@ -2428,7 +2388,7 @@ module aptos_framework::stake {
     public entry fun test_active_validator_having_insufficient_remaining_stake_after_withdrawal_gets_kicked(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
         let (_sk, pk, pop) = generate_identity();
         initialize_test_validator(&pk, &pop, validator, 100, true, true);
@@ -2456,7 +2416,7 @@ module aptos_framework::stake {
         aptos_framework: &signer,
         validator: &signer,
         validator_2: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
         let (_sk_1, pk_1, pop_1) = generate_identity();
         let (_sk_2, pk_2, pop_2) = generate_identity();
@@ -2500,7 +2460,7 @@ module aptos_framework::stake {
         aptos_framework: &signer,
         validator: &signer,
         validator_2: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
         let (_sk_1, pk_1, pop_1) = generate_identity();
         let (_sk_2, pk_2, pop_2) = generate_identity();
@@ -2531,7 +2491,7 @@ module aptos_framework::stake {
         aptos_framework: &signer,
         validator_1: &signer,
         validator_2: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         // Only 50% voting power increase is allowed in each epoch.
         initialize_for_test_custom(aptos_framework, 50, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 10, 50);
         let (_sk_1, pk_1, pop_1) = generate_identity();
@@ -2552,7 +2512,7 @@ module aptos_framework::stake {
         validator_1: &signer,
         validator_2: &signer,
         validator_3: &signer
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         let validator_1_address = signer::address_of(validator_1);
         let validator_2_address = signer::address_of(validator_2);
         let validator_3_address = signer::address_of(validator_3);
@@ -2646,7 +2606,7 @@ module aptos_framework::stake {
     public entry fun test_delegated_staking_with_owner_cap(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test_custom(aptos_framework, 100, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 100, 100);
         let (_sk, pk, pop) = generate_identity();
         initialize_test_validator(&pk, &pop, validator, 0, false, false);
@@ -2699,7 +2659,7 @@ module aptos_framework::stake {
     public entry fun test_validator_cannot_join_post_genesis(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test_custom(aptos_framework, 100, 10000, LOCKUP_CYCLE_SECONDS, false, 1, 100, 100);
 
         // Joining the validator set should fail as post genesis validator set change is not allowed.
@@ -2712,7 +2672,7 @@ module aptos_framework::stake {
     public entry fun test_invalid_pool_address(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
         let (_sk, pk, pop) = generate_identity();
         initialize_test_validator(&pk, &pop, validator, 100, true, true);
@@ -2724,7 +2684,7 @@ module aptos_framework::stake {
     public entry fun test_validator_cannot_leave_post_genesis(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test_custom(aptos_framework, 100, 10000, LOCKUP_CYCLE_SECONDS, false, 1, 100, 100);
         let (_sk, pk, pop) = generate_identity();
         initialize_test_validator(&pk, &pop, validator, 100, false, false);
@@ -2753,7 +2713,7 @@ module aptos_framework::stake {
         validator_3: &signer,
         validator_4: &signer,
         validator_5: &signer,
-    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         let v1_addr = signer::address_of(validator_1);
         let v2_addr = signer::address_of(validator_2);
         let v3_addr = signer::address_of(validator_3);
@@ -2826,7 +2786,7 @@ module aptos_framework::stake {
         validator_3: &signer,
         validator_4: &signer,
         validator_5: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         let v1_addr = signer::address_of(validator_1);
         let v2_addr = signer::address_of(validator_2);
         let v3_addr = signer::address_of(validator_3);
@@ -2889,7 +2849,7 @@ module aptos_framework::stake {
         aptos_framework: &signer,
         validator_1: &signer,
         validator_2: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
 
         let validator_1_address = signer::address_of(validator_1);
@@ -2937,7 +2897,7 @@ module aptos_framework::stake {
         aptos_framework: &signer,
         validator_1: &signer,
         validator_2: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
 
         let genesis_time_in_secs = timestamp::now_seconds();
@@ -2993,7 +2953,7 @@ module aptos_framework::stake {
     public entry fun test_update_performance_statistics_should_not_fail_due_to_out_of_bounds(
         aptos_framework: &signer,
         validator: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
 
         let validator_address = signer::address_of(validator);
@@ -3116,7 +3076,7 @@ module aptos_framework::stake {
         aptos_framework: &signer,
         validator_1: &signer,
         validator_2: &signer,
-    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires AllowedValidators, OwnerCapability, StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         initialize_for_test(aptos_framework);
         let (_sk_1, pk_1, pop_1) = generate_identity();
         let (_sk_2, pk_2, pop_2) = generate_identity();
@@ -3133,7 +3093,7 @@ module aptos_framework::stake {
 
     #[test_only]
     public fun end_epoch(
-    ) acquires StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+    ) acquires StakePool, AptosCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet {
         // Set the number of blocks to 1, to give out rewards to non-failing validators.
         set_validator_perf_at_least_one_block();
         timestamp::fast_forward_seconds(EPOCH_DURATION);
@@ -3213,74 +3173,4 @@ module aptos_framework::stake {
         let (numerator, denominator) = staking_config::get_reward_rate(&staking_config::get());
         amount + amount * numerator / denominator
     }
-
-    #[test_only]
-    public fun get_validator_fee(validator_addr: address): u64 acquires ValidatorFees {
-        let fees_table = &borrow_global(@aptos_framework).fees_table;
-        let coin = table::borrow(fees_table, validator_addr);
-        coin::value(coin)
-    }
-
-    #[test_only]
-    public fun assert_no_fees_for_validator(validator_addr: address) acquires ValidatorFees {
-        let fees_table = &borrow_global(@aptos_framework).fees_table;
-        assert!(!table::contains(fees_table, validator_addr), 0);
-    }
-
-    #[test_only]
-    const COLLECT_AND_DISTRIBUTE_GAS_FEES: u64 = 6;
-
-    #[test(aptos_framework = @0x1, validator_1 = @0x123, validator_2 = @0x234, validator_3 = @0x345)]
-    fun test_distribute_validator_fees(
-        aptos_framework: &signer,
-        validator_1: &signer,
-        validator_2: &signer,
-        validator_3: &signer,
-    ) acquires AllowedValidators, AptosCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
-        // Make sure that fees collection and distribution is enabled.
-        features::change_feature_flags_for_testing(aptos_framework, vector[COLLECT_AND_DISTRIBUTE_GAS_FEES], vector[]);
-        assert!(features::collect_and_distribute_gas_fees(), 0);
-
-        // Initialize staking and validator fees table.
-        initialize_for_test(aptos_framework);
-        initialize_validator_fees(aptos_framework);
-
-        let validator_1_address = signer::address_of(validator_1);
-        let validator_2_address = signer::address_of(validator_2);
-        let validator_3_address = signer::address_of(validator_3);
-
-        // Validators join the set and epoch ends.
-        let (_sk_1, pk_1, pop_1) = generate_identity();
-        let (_sk_2, pk_2, pop_2) = generate_identity();
-        let (_sk_3, pk_3, pop_3) = generate_identity();
-        initialize_test_validator(&pk_1, &pop_1, validator_1, 100, true, false);
-        initialize_test_validator(&pk_2, &pop_2, validator_2, 100, true, false);
-        initialize_test_validator(&pk_3, &pop_3, validator_3, 100, true, true);
-
-        // Next, simulate fees collection during three blocks, where proposers are
-        // validators 1, 2, and 1 again.
-        add_transaction_fee(validator_1_address, mint_coins(100));
-        add_transaction_fee(validator_2_address, mint_coins(500));
-        add_transaction_fee(validator_1_address, mint_coins(200));
-
-        // Fess have to be assigned to the right validators, but not
-        // distributed yet.
-        assert!(get_validator_fee(validator_1_address) == 300, 0);
-        assert!(get_validator_fee(validator_2_address) == 500, 0);
-        assert_no_fees_for_validator(validator_3_address);
-        assert_validator_state(validator_1_address, 100, 0, 0, 0, 2);
-        assert_validator_state(validator_2_address, 100, 0, 0, 0, 1);
-        assert_validator_state(validator_3_address, 100, 0, 0, 0, 0);
-
-        end_epoch();
-
-        // Epoch ended. Validators must have recieved their rewards and, most importantly,
-        // their fees.
-        assert_no_fees_for_validator(validator_1_address);
-        assert_no_fees_for_validator(validator_2_address);
-        assert_no_fees_for_validator(validator_3_address);
-        assert_validator_state(validator_1_address, 401, 0, 0, 0, 2);
-        assert_validator_state(validator_2_address, 601, 0, 0, 0, 1);
-        assert_validator_state(validator_3_address, 101, 0, 0, 0, 0);
-    }
 }
diff --git a/aptos-move/framework/aptos-framework/sources/stake.spec.move b/aptos-move/framework/aptos-framework/sources/stake.spec.move
index 44101fbcb134cc..747c8212a3fa4f 100644
--- a/aptos-move/framework/aptos-framework/sources/stake.spec.move
+++ b/aptos-move/framework/aptos-framework/sources/stake.spec.move
@@ -118,13 +118,6 @@ spec aptos_framework::stake {
     // Function specifications
     // -----------------------
 
-    spec initialize_validator_fees(aptos_framework: &signer) {
-        let aptos_addr = signer::address_of(aptos_framework);
-        aborts_if !system_addresses::is_aptos_framework_address(aptos_addr);
-        aborts_if exists(aptos_addr);
-        ensures exists(aptos_addr);
-    }
-
     spec initialize_validator(
         account: &signer,
         consensus_pubkey: vector,
@@ -496,17 +489,10 @@ spec aptos_framework::stake {
         let post post_stake_pool = global(pool_address);
         let post post_active_value = post_stake_pool.active.value;
         let post post_pending_inactive_value = post_stake_pool.pending_inactive.value;
-        let fees_table = global(@aptos_framework).fees_table;
-        let post post_fees_table = global(@aptos_framework).fees_table;
         let post post_inactive_value = post_stake_pool.inactive.value;
         ensures post_stake_pool.pending_active.value == 0;
         // the amount stored in the stake pool should not changed after the update
-        ensures if (features::spec_is_enabled(features::COLLECT_AND_DISTRIBUTE_GAS_FEES) && table::spec_contains(fees_table, pool_address)) {
-            !table::spec_contains(post_fees_table, pool_address) &&
-            post_active_value == stake_pool.active.value + rewards_amount_1 + stake_pool.pending_active.value + table::spec_get(fees_table, pool_address).value
-        } else {
-            post_active_value == stake_pool.active.value + rewards_amount_1 + stake_pool.pending_active.value
-        };
+        ensures post_active_value == stake_pool.active.value + rewards_amount_1 + stake_pool.pending_active.value;
         // when current lockup cycle has expired, pending inactive should be fully unlocked and moved into inactive
         ensures if (spec_get_reconfig_start_time_secs() >= stake_pool.locked_until_secs) {
             post_pending_inactive_value == 0 &&
@@ -527,7 +513,6 @@ spec aptos_framework::stake {
         aborts_if global(pool_address).validator_index >= len(validator_perf.validators);
 
         let aptos_addr = type_info::type_of().account_address;
-        aborts_if !exists(aptos_addr);
 
         let stake_pool = global(pool_address);
 
@@ -726,20 +711,6 @@ spec aptos_framework::stake {
             active == initial_stake_amount;
     }
 
-    spec add_transaction_fee(validator_addr: address, fee: Coin) {
-        aborts_if !exists(@aptos_framework);
-        let fees_table = global(@aptos_framework).fees_table;
-        let post post_fees_table = global(@aptos_framework).fees_table;
-        let collected_fee = table::spec_get(fees_table, validator_addr);
-        let post post_collected_fee = table::spec_get(post_fees_table, validator_addr);
-        ensures if (table::spec_contains(fees_table, validator_addr)) {
-            post_collected_fee.value == collected_fee.value + fee.value
-        } else {
-            table::spec_contains(post_fees_table, validator_addr) &&
-            table::spec_get(post_fees_table, validator_addr) == fee
-        };
-    }
-
     spec update_voting_power_increase(increase_amount: u64) {
         requires !reconfiguration_state::spec_is_in_progress();
         aborts_if !exists(@aptos_framework);
@@ -920,7 +891,6 @@ spec aptos_framework::stake {
         requires exists(@aptos_framework);
         requires exists(@aptos_framework) || !features::spec_periodical_reward_rate_decrease_enabled();
         requires exists(@aptos_framework);
-        requires exists(@aptos_framework);
     }
 
     // Adding helper function in staking_config leads to an unexpected error
diff --git a/aptos-move/framework/aptos-framework/sources/transaction_fee.move b/aptos-move/framework/aptos-framework/sources/transaction_fee.move
index 55eb05c85b6599..f1f4e0b0b439fc 100644
--- a/aptos-move/framework/aptos-framework/sources/transaction_fee.move
+++ b/aptos-move/framework/aptos-framework/sources/transaction_fee.move
@@ -1,9 +1,8 @@
 /// This module provides an interface to burn or collect and redistribute transaction fees.
 module aptos_framework::transaction_fee {
-    use aptos_framework::coin::{Self, AggregatableCoin, BurnCapability, Coin, MintCapability};
+    use aptos_framework::coin::{Self, AggregatableCoin, BurnCapability, MintCapability};
     use aptos_framework::aptos_account;
     use aptos_framework::aptos_coin::AptosCoin;
-    use aptos_framework::stake;
     use aptos_framework::fungible_asset::BurnRef;
     use aptos_framework::system_addresses;
     use std::error;
@@ -44,6 +43,7 @@ module aptos_framework::transaction_fee {
         mint_cap: MintCapability,
     }
 
+    #[deprecated]
     /// Stores information about the block proposer and the amount of fees
     /// collected when executing the block.
     struct CollectedFeesPerBlock has key {
@@ -85,126 +85,19 @@ module aptos_framework::transaction_fee {
         storage_fee_refund_octas: u64,
     }
 
+    #[deprecated]
     /// Initializes the resource storing information about gas fees collection and
     /// distribution. Should be called by on-chain governance.
-    public fun initialize_fee_collection_and_distribution(aptos_framework: &signer, burn_percentage: u8) {
-        system_addresses::assert_aptos_framework(aptos_framework);
-        assert!(
-            !exists(@aptos_framework),
-            error::already_exists(EALREADY_COLLECTING_FEES)
-        );
-        assert!(burn_percentage <= 100, error::out_of_range(EINVALID_BURN_PERCENTAGE));
-
-        // Make sure stakng module is aware of transaction fees collection.
-        stake::initialize_validator_fees(aptos_framework);
-
-        // Initially, no fees are collected and the block proposer is not set.
-        let collected_fees = CollectedFeesPerBlock {
-            amount: coin::initialize_aggregatable_coin(aptos_framework),
-            proposer: option::none(),
-            burn_percentage,
-        };
-        move_to(aptos_framework, collected_fees);
-    }
-
-    fun is_fees_collection_enabled(): bool {
-        exists(@aptos_framework)
+    public fun initialize_fee_collection_and_distribution(_aptos_framework: &signer, _burn_percentage: u8) {
+        abort error::not_implemented(ENO_LONGER_SUPPORTED)
     }
 
     /// Sets the burn percentage for collected fees to a new value. Should be called by on-chain governance.
     public fun upgrade_burn_percentage(
-        aptos_framework: &signer,
-        new_burn_percentage: u8
-    ) acquires AptosCoinCapabilities, CollectedFeesPerBlock {
-        system_addresses::assert_aptos_framework(aptos_framework);
-        assert!(new_burn_percentage <= 100, error::out_of_range(EINVALID_BURN_PERCENTAGE));
-
-        // Prior to upgrading the burn percentage, make sure to process collected
-        // fees. Otherwise we would use the new (incorrect) burn_percentage when
-        // processing fees later!
-        process_collected_fees();
-
-        if (is_fees_collection_enabled()) {
-            // Upgrade has no effect unless fees are being collected.
-            let burn_percentage = &mut borrow_global_mut(@aptos_framework).burn_percentage;
-            *burn_percentage = new_burn_percentage
-        }
-    }
-
-    /// Registers the proposer of the block for gas fees collection. This function
-    /// can only be called at the beginning of the block.
-    public(friend) fun register_proposer_for_fee_collection(proposer_addr: address) acquires CollectedFeesPerBlock {
-        if (is_fees_collection_enabled()) {
-            let collected_fees = borrow_global_mut(@aptos_framework);
-            let _ = option::swap_or_fill(&mut collected_fees.proposer, proposer_addr);
-        }
-    }
-
-    /// Burns a specified fraction of the coin.
-    fun burn_coin_fraction(coin: &mut Coin, burn_percentage: u8) acquires AptosCoinCapabilities {
-        assert!(burn_percentage <= 100, error::out_of_range(EINVALID_BURN_PERCENTAGE));
-
-        let collected_amount = coin::value(coin);
-        spec {
-            // We assume that `burn_percentage * collected_amount` does not overflow.
-            assume burn_percentage * collected_amount <= MAX_U64;
-        };
-        let amount_to_burn = (burn_percentage as u64) * collected_amount / 100;
-        if (amount_to_burn > 0) {
-            let coin_to_burn = coin::extract(coin, amount_to_burn);
-            coin::burn(
-                coin_to_burn,
-                &borrow_global(@aptos_framework).burn_cap,
-            );
-        }
-    }
-
-    /// Calculates the fee which should be distributed to the block proposer at the
-    /// end of an epoch, and records it in the system. This function can only be called
-    /// at the beginning of the block or during reconfiguration.
-    public(friend) fun process_collected_fees() acquires AptosCoinCapabilities, CollectedFeesPerBlock {
-        if (!is_fees_collection_enabled()) {
-            return
-        };
-        let collected_fees = borrow_global_mut(@aptos_framework);
-
-        // If there are no collected fees, only unset the proposer. See the rationale for
-        // setting proposer to option::none() below.
-        if (coin::is_aggregatable_coin_zero(&collected_fees.amount)) {
-            if (option::is_some(&collected_fees.proposer)) {
-                let _ = option::extract(&mut collected_fees.proposer);
-            };
-            return
-        };
-
-        // Otherwise get the collected fee, and check if it can distributed later.
-        let coin = coin::drain_aggregatable_coin(&mut collected_fees.amount);
-        if (option::is_some(&collected_fees.proposer)) {
-            // Extract the address of proposer here and reset it to option::none(). This
-            // is particularly useful to avoid any undesired side-effects where coins are
-            // collected but never distributed or distributed to the wrong account.
-            // With this design, processing collected fees enforces that all fees will be burnt
-            // unless the proposer is specified in the block prologue. When we have a governance
-            // proposal that triggers reconfiguration, we distribute pending fees and burn the
-            // fee for the proposal. Otherwise, that fee would be leaked to the next block.
-            let proposer = option::extract(&mut collected_fees.proposer);
-
-            // Since the block can be produced by the VM itself, we have to make sure we catch
-            // this case.
-            if (proposer == @vm_reserved) {
-                burn_coin_fraction(&mut coin, 100);
-                coin::destroy_zero(coin);
-                return
-            };
-
-            burn_coin_fraction(&mut coin, collected_fees.burn_percentage);
-            stake::add_transaction_fee(proposer, coin);
-            return
-        };
-
-        // If checks did not pass, simply burn all collected coins and return none.
-        burn_coin_fraction(&mut coin, 100);
-        coin::destroy_zero(coin)
+        _aptos_framework: &signer,
+        _new_burn_percentage: u8
+    ) {
+        abort error::not_implemented(ENO_LONGER_SUPPORTED)
     }
 
     /// Burn transaction fees in epilogue.
@@ -235,17 +128,6 @@ module aptos_framework::transaction_fee {
         coin::force_deposit(account, refund_coin);
     }
 
-    /// Collect transaction fees in epilogue.
-    public(friend) fun collect_fee(account: address, fee: u64) acquires CollectedFeesPerBlock {
-        let collected_fees = borrow_global_mut(@aptos_framework);
-
-        // Here, we are always optimistic and always collect fees. If the proposer is not set,
-        // or we cannot redistribute fees later for some reason (e.g. account cannot receive AptoCoin)
-        // we burn them all at once. This way we avoid having a check for every transaction epilogue.
-        let collected_amount = &mut collected_fees.amount;
-        coin::collect_into_aggregatable_coin(account, fee, collected_amount);
-    }
-
     /// Only called during genesis.
     public(friend) fun store_aptos_coin_burn_cap(aptos_framework: &signer, burn_cap: BurnCapability) {
         system_addresses::assert_aptos_framework(aptos_framework);
@@ -283,175 +165,4 @@ module aptos_framework::transaction_fee {
     fun emit_fee_statement(fee_statement: FeeStatement) {
         event::emit(fee_statement)
     }
-
-    #[test_only]
-    use aptos_framework::aggregator_factory;
-    #[test_only]
-    use aptos_framework::object;
-
-    #[test(aptos_framework = @aptos_framework)]
-    fun test_initialize_fee_collection_and_distribution(aptos_framework: signer) acquires CollectedFeesPerBlock {
-        aggregator_factory::initialize_aggregator_factory_for_test(&aptos_framework);
-        initialize_fee_collection_and_distribution(&aptos_framework, 25);
-
-        // Check struct has been published.
-        assert!(exists(@aptos_framework), 0);
-
-        // Check that initial balance is 0 and there is no proposer set.
-        let collected_fees = borrow_global(@aptos_framework);
-        assert!(coin::is_aggregatable_coin_zero(&collected_fees.amount), 0);
-        assert!(option::is_none(&collected_fees.proposer), 0);
-        assert!(collected_fees.burn_percentage == 25, 0);
-    }
-
-    #[test(aptos_framework = @aptos_framework)]
-    fun test_burn_fraction_calculation(aptos_framework: signer) acquires AptosCoinCapabilities {
-        use aptos_framework::aptos_coin;
-        let (burn_cap, mint_cap) = aptos_coin::initialize_for_test(&aptos_framework);
-        store_aptos_coin_burn_cap(&aptos_framework, burn_cap);
-
-        let c1 = coin::mint(100, &mint_cap);
-        assert!(*option::borrow(&coin::supply()) == 100, 0);
-
-        // Burning 25%.
-        burn_coin_fraction(&mut c1, 25);
-        assert!(coin::value(&c1) == 75, 0);
-        assert!(*option::borrow(&coin::supply()) == 75, 0);
-
-        // Burning 0%.
-        burn_coin_fraction(&mut c1, 0);
-        assert!(coin::value(&c1) == 75, 0);
-        assert!(*option::borrow(&coin::supply()) == 75, 0);
-
-        // Burning remaining 100%.
-        burn_coin_fraction(&mut c1, 100);
-        assert!(coin::value(&c1) == 0, 0);
-        assert!(*option::borrow(&coin::supply()) == 0, 0);
-
-        coin::destroy_zero(c1);
-        let c2 = coin::mint(10, &mint_cap);
-        assert!(*option::borrow(&coin::supply()) == 10, 0);
-
-        burn_coin_fraction(&mut c2, 5);
-        assert!(coin::value(&c2) == 10, 0);
-        assert!(*option::borrow(&coin::supply()) == 10, 0);
-
-        burn_coin_fraction(&mut c2, 100);
-        coin::destroy_zero(c2);
-        coin::destroy_burn_cap(burn_cap);
-        coin::destroy_mint_cap(mint_cap);
-    }
-
-    #[test(aptos_framework = @aptos_framework, alice = @0xa11ce, bob = @0xb0b, carol = @0xca101)]
-    fun test_fees_distribution(
-        aptos_framework: signer,
-        alice: signer,
-        bob: signer,
-        carol: signer,
-    ) acquires AptosCoinCapabilities, CollectedFeesPerBlock {
-        use std::signer;
-        use aptos_framework::aptos_account;
-        use aptos_framework::aptos_coin;
-
-        // Initialization.
-        let (burn_cap, mint_cap) = aptos_coin::initialize_for_test(&aptos_framework);
-        store_aptos_coin_burn_cap(&aptos_framework, burn_cap);
-        initialize_fee_collection_and_distribution(&aptos_framework, 10);
-
-        // Create dummy accounts.
-        let alice_addr = signer::address_of(&alice);
-        let bob_addr = signer::address_of(&bob);
-        let carol_addr = signer::address_of(&carol);
-        aptos_account::create_account(alice_addr);
-        aptos_account::create_account(bob_addr);
-        aptos_account::create_account(carol_addr);
-        assert!(object::object_address(&coin::ensure_paired_metadata()) == @aptos_fungible_asset, 0);
-        coin::deposit(alice_addr, coin::mint(10000, &mint_cap));
-        coin::deposit(bob_addr, coin::mint(10000, &mint_cap));
-        coin::deposit(carol_addr, coin::mint(10000, &mint_cap));
-        assert!(*option::borrow(&coin::supply()) == 30000, 0);
-
-        // Block 1 starts.
-        process_collected_fees();
-        register_proposer_for_fee_collection(alice_addr);
-
-        // Check that there was no fees distribution in the first block.
-        let collected_fees = borrow_global(@aptos_framework);
-        assert!(coin::is_aggregatable_coin_zero(&collected_fees.amount), 0);
-        assert!(*option::borrow(&collected_fees.proposer) == alice_addr, 0);
-        assert!(*option::borrow(&coin::supply()) == 30000, 0);
-
-        // Simulate transaction fee collection - here we simply collect some fees from Bob.
-        collect_fee(bob_addr, 100);
-        collect_fee(bob_addr, 500);
-        collect_fee(bob_addr, 400);
-
-        // Now Bob must have 1000 less in his account. Alice and Carol have the same amounts.
-        assert!(coin::balance(alice_addr) == 10000, 0);
-        assert!(coin::balance(bob_addr) == 9000, 0);
-        assert!(coin::balance(carol_addr) == 10000, 0);
-
-        // Block 2 starts.
-        process_collected_fees();
-        register_proposer_for_fee_collection(bob_addr);
-
-        // Collected fees from Bob must have been assigned to Alice.
-        assert!(stake::get_validator_fee(alice_addr) == 900, 0);
-        assert!(coin::balance(alice_addr) == 10000, 0);
-        assert!(coin::balance(bob_addr) == 9000, 0);
-        assert!(coin::balance(carol_addr) == 10000, 0);
-
-        // Also, aggregator coin is drained and total supply is slightly changed (10% of 1000 is burnt).
-        let collected_fees = borrow_global(@aptos_framework);
-        assert!(coin::is_aggregatable_coin_zero(&collected_fees.amount), 0);
-        assert!(*option::borrow(&collected_fees.proposer) == bob_addr, 0);
-        assert!(*option::borrow(&coin::supply()) == 29900, 0);
-
-        // Simulate transaction fee collection one more time.
-        collect_fee(bob_addr, 5000);
-        collect_fee(bob_addr, 4000);
-
-        assert!(coin::balance(alice_addr) == 10000, 0);
-        assert!(coin::balance(bob_addr) == 0, 0);
-        assert!(coin::balance(carol_addr) == 10000, 0);
-
-        // Block 3 starts.
-        process_collected_fees();
-        register_proposer_for_fee_collection(carol_addr);
-
-        // Collected fees should have been assigned to Bob because he was the peoposer.
-        assert!(stake::get_validator_fee(alice_addr) == 900, 0);
-        assert!(coin::balance(alice_addr) == 10000, 0);
-        assert!(stake::get_validator_fee(bob_addr) == 8100, 0);
-        assert!(coin::balance(bob_addr) == 0, 0);
-        assert!(coin::balance(carol_addr) == 10000, 0);
-
-        // Again, aggregator coin is drained and total supply is changed by 10% of 9000.
-        let collected_fees = borrow_global(@aptos_framework);
-        assert!(coin::is_aggregatable_coin_zero(&collected_fees.amount), 0);
-        assert!(*option::borrow(&collected_fees.proposer) == carol_addr, 0);
-        assert!(*option::borrow(&coin::supply()) == 29000, 0);
-
-        // Simulate transaction fee collection one last time.
-        collect_fee(alice_addr, 1000);
-        collect_fee(alice_addr, 1000);
-
-        // Block 4 starts.
-        process_collected_fees();
-        register_proposer_for_fee_collection(alice_addr);
-
-        // Check that 2000 was collected from Alice.
-        assert!(coin::balance(alice_addr) == 8000, 0);
-        assert!(coin::balance(bob_addr) == 0, 0);
-
-        // Carol must have some fees assigned now.
-        let collected_fees = borrow_global(@aptos_framework);
-        assert!(stake::get_validator_fee(carol_addr) == 1800, 0);
-        assert!(coin::is_aggregatable_coin_zero(&collected_fees.amount), 0);
-        assert!(*option::borrow(&collected_fees.proposer) == alice_addr, 0);
-        assert!(*option::borrow(&coin::supply()) == 28800, 0);
-
-        coin::destroy_burn_cap(burn_cap);
-        coin::destroy_mint_cap(mint_cap);
-    }
 }
diff --git a/aptos-move/framework/aptos-framework/sources/transaction_fee.spec.move b/aptos-move/framework/aptos-framework/sources/transaction_fee.spec.move
index e11883f4807882..7571861410c0a6 100644
--- a/aptos-move/framework/aptos-framework/sources/transaction_fee.spec.move
+++ b/aptos-move/framework/aptos-framework/sources/transaction_fee.spec.move
@@ -67,132 +67,7 @@ spec aptos_framework::transaction_fee {
         invariant burn_percentage <= 100;
     }
 
-    spec initialize_fee_collection_and_distribution(aptos_framework: &signer, burn_percentage: u8) {
-        use std::signer;
-        use aptos_framework::stake::ValidatorFees;
-        use aptos_framework::aggregator_factory;
-        use aptos_framework::system_addresses;
-
-        // property 2: The initialization function may only be called once.
-        /// [high-level-req-2]
-        aborts_if exists(@aptos_framework);
-        aborts_if burn_percentage > 100;
-
-        let aptos_addr = signer::address_of(aptos_framework);
-        // property 3: Only the admin address is authorized to call the initialization function.
-        /// [high-level-req-3]
-        aborts_if !system_addresses::is_aptos_framework_address(aptos_addr);
-        aborts_if exists(aptos_addr);
-
-        include system_addresses::AbortsIfNotAptosFramework { account: aptos_framework };
-        include aggregator_factory::CreateAggregatorInternalAbortsIf;
-        aborts_if exists(aptos_addr);
-
-        ensures exists(aptos_addr);
-        ensures exists(aptos_addr);
-    }
-
-    spec upgrade_burn_percentage(aptos_framework: &signer, new_burn_percentage: u8) {
-        use std::signer;
-
-        // Percentage validation
-        aborts_if new_burn_percentage > 100;
-        // Signer validation
-        let aptos_addr = signer::address_of(aptos_framework);
-        aborts_if !system_addresses::is_aptos_framework_address(aptos_addr);
-
-        // property 5: Prior to upgrading the burn percentage, it must process all the fees collected up to that point.
-        // property 6: Ensure the presence of the resource.
-        // Requirements and ensures conditions of `process_collected_fees`
-        /// [high-level-req-5]
-        /// [high-level-req-6.3]
-        include ProcessCollectedFeesRequiresAndEnsures;
-
-        // The effect of upgrading the burn percentage
-        ensures exists(@aptos_framework) ==>
-            global(@aptos_framework).burn_percentage == new_burn_percentage;
-    }
-
-    spec register_proposer_for_fee_collection(proposer_addr: address) {
-        aborts_if false;
-        // property 6: Ensure the presence of the resource.
-        /// [high-level-req-6.1]
-        ensures is_fees_collection_enabled() ==>
-            option::spec_borrow(global(@aptos_framework).proposer) == proposer_addr;
-    }
-
-    spec burn_coin_fraction(coin: &mut Coin, burn_percentage: u8) {
-        use aptos_framework::coin::CoinInfo;
-        use aptos_framework::aptos_coin::AptosCoin;
-
-        requires burn_percentage <= 100;
-        requires exists(@aptos_framework);
-        requires exists>(@aptos_framework);
-
-        let amount_to_burn = (burn_percentage * coin::value(coin)) / 100;
-        // include (amount_to_burn > 0) ==> coin::AbortsIfNotExistCoinInfo;
-        include amount_to_burn > 0 ==> coin::CoinSubAbortsIf { amount: amount_to_burn };
-        ensures coin.value == old(coin).value - amount_to_burn;
-    }
-
-    spec fun collectedFeesAggregator(): AggregatableCoin {
-        global(@aptos_framework).amount
-    }
-
-    spec schema RequiresCollectedFeesPerValueLeqBlockAptosSupply {
-        use aptos_framework::optional_aggregator;
-        use aptos_framework::aggregator;
-        let maybe_supply = coin::get_coin_supply_opt();
-        // property 6: Ensure the presence of the resource.
-        requires
-            (is_fees_collection_enabled() && option::is_some(maybe_supply)) ==>
-                (aggregator::spec_aggregator_get_val(global(@aptos_framework).amount.value) <=
-                    optional_aggregator::optional_aggregator_value(
-                        option::spec_borrow(coin::get_coin_supply_opt())
-                    ));
-    }
-
-    spec schema ProcessCollectedFeesRequiresAndEnsures {
-        use aptos_framework::coin::CoinInfo;
-        use aptos_framework::aptos_coin::AptosCoin;
-        use aptos_framework::aggregator;
-        use aptos_std::table;
-
-        requires exists(@aptos_framework);
-        requires exists(@aptos_framework);
-        requires exists>(@aptos_framework);
-        include RequiresCollectedFeesPerValueLeqBlockAptosSupply;
-
-        aborts_if false;
-
-        let collected_fees = global(@aptos_framework);
-        let post post_collected_fees = global(@aptos_framework);
-        let pre_amount = aggregator::spec_aggregator_get_val(collected_fees.amount.value);
-        let post post_amount = aggregator::spec_aggregator_get_val(post_collected_fees.amount.value);
-        let fees_table = global(@aptos_framework).fees_table;
-        let post post_fees_table = global(@aptos_framework).fees_table;
-        let proposer = option::spec_borrow(collected_fees.proposer);
-        let fee_to_add = pre_amount - pre_amount * collected_fees.burn_percentage / 100;
-        ensures is_fees_collection_enabled() ==> option::spec_is_none(post_collected_fees.proposer) && post_amount == 0;
-        ensures is_fees_collection_enabled() && aggregator::spec_read(collected_fees.amount.value) > 0 &&
-            option::spec_is_some(collected_fees.proposer) ==>
-            if (proposer != @vm_reserved) {
-                if (table::spec_contains(fees_table, proposer)) {
-                    table::spec_get(post_fees_table, proposer).value == table::spec_get(
-                        fees_table,
-                        proposer
-                    ).value + fee_to_add
-                } else {
-                    table::spec_get(post_fees_table, proposer).value == fee_to_add
-                }
-            } else {
-                option::spec_is_none(post_collected_fees.proposer) && post_amount == 0
-            };
-    }
-
-    spec process_collected_fees() {
-        /// [high-level-req-6.2]
-        include ProcessCollectedFeesRequiresAndEnsures;
+    spec initialize_fee_collection_and_distribution(_aptos_framework: &signer, _burn_percentage: u8) {
     }
 
     /// `AptosCoinCapabilities` should be exists.
@@ -264,30 +139,6 @@ spec aptos_framework::transaction_fee {
         ensures post_supply == supply + refund;
     }
 
-    spec collect_fee(account: address, fee: u64) {
-        use aptos_framework::aggregator;
-        // TODO(fa_migration)
-        pragma verify = false;
-
-        let collected_fees = global(@aptos_framework).amount;
-        let aggr = collected_fees.value;
-        let coin_store = global>(account);
-        aborts_if !exists(@aptos_framework);
-        aborts_if fee > 0 && !exists>(account);
-        aborts_if fee > 0 && coin_store.coin.value < fee;
-        aborts_if fee > 0 && aggregator::spec_aggregator_get_val(aggr)
-            + fee > aggregator::spec_get_limit(aggr);
-        aborts_if fee > 0 && aggregator::spec_aggregator_get_val(aggr)
-            + fee > MAX_U128;
-
-        let post post_coin_store = global>(account);
-        let post post_collected_fees = global(@aptos_framework).amount;
-        ensures post_coin_store.coin.value == coin_store.coin.value - fee;
-        ensures aggregator::spec_aggregator_get_val(post_collected_fees.value) == aggregator::spec_aggregator_get_val(
-            aggr
-        ) + fee;
-    }
-
     /// Ensure caller is admin.
     /// Aborts if `AptosCoinCapabilities` already exists.
     spec store_aptos_coin_burn_cap(aptos_framework: &signer, burn_cap: BurnCapability) {
diff --git a/aptos-move/framework/aptos-framework/sources/transaction_validation.move b/aptos-move/framework/aptos-framework/sources/transaction_validation.move
index c3496215972e6f..f9821da0b5486a 100644
--- a/aptos-move/framework/aptos-framework/sources/transaction_validation.move
+++ b/aptos-move/framework/aptos-framework/sources/transaction_validation.move
@@ -462,26 +462,11 @@ module aptos_framework::transaction_validation {
                 );
             };
 
-            let amount_to_burn = if (features::collect_and_distribute_gas_fees()) {
-                // TODO(gas): We might want to distinguish the refundable part of the charge and burn it or track
-                // it separately, so that we don't increase the total supply by refunding.
-
-                // If transaction fees are redistributed to validators, collect them here for
-                // later redistribution.
-                transaction_fee::collect_fee(gas_payer, transaction_fee_amount);
-                0
-            } else {
-                // Otherwise, just burn the fee.
-                // TODO: this branch should be removed completely when transaction fee collection
-                // is tested and is fully proven to work well.
-                transaction_fee_amount
-            };
-
-            if (amount_to_burn > storage_fee_refunded) {
-                let burn_amount = amount_to_burn - storage_fee_refunded;
+            if (transaction_fee_amount > storage_fee_refunded) {
+                let burn_amount = transaction_fee_amount - storage_fee_refunded;
                 transaction_fee::burn_fee(gas_payer, burn_amount);
-            } else if (amount_to_burn < storage_fee_refunded) {
-                let mint_amount = storage_fee_refunded - amount_to_burn;
+            } else if (transaction_fee_amount < storage_fee_refunded) {
+                let mint_amount = storage_fee_refunded - transaction_fee_amount;
                 transaction_fee::mint_and_refund(gas_payer, mint_amount)
             };
         };
diff --git a/aptos-move/framework/aptos-framework/sources/transaction_validation.spec.move b/aptos-move/framework/aptos-framework/sources/transaction_validation.spec.move
index 799e71e4142049..d97568e00374a6 100644
--- a/aptos-move/framework/aptos-framework/sources/transaction_validation.spec.move
+++ b/aptos-move/framework/aptos-framework/sources/transaction_validation.spec.move
@@ -344,12 +344,11 @@ spec aptos_framework::transaction_validation {
         use std::option;
         use aptos_std::type_info;
         use aptos_framework::account::{Account};
-        use aptos_framework::aggregator;
         use aptos_framework::aptos_coin::{AptosCoin};
         use aptos_framework::coin;
         use aptos_framework::coin::{CoinStore, CoinInfo};
         use aptos_framework::optional_aggregator;
-        use aptos_framework::transaction_fee::{AptosCoinCapabilities, AptosCoinMintCapability, CollectedFeesPerBlock};
+        use aptos_framework::transaction_fee::{AptosCoinCapabilities, AptosCoinMintCapability};
 
         account: signer;
         gas_payer: address;
@@ -379,25 +378,9 @@ spec aptos_framework::transaction_validation {
         // ensures balance == pre_balance - transaction_fee_amount + storage_fee_refunded;
         ensures account.sequence_number == pre_account.sequence_number + 1;
 
-
-        // Check fee collection.
-        let collect_fee_enabled = features::spec_is_enabled(features::COLLECT_AND_DISTRIBUTE_GAS_FEES);
-        let collected_fees = global(@aptos_framework).amount;
-        let aggr = collected_fees.value;
-        let aggr_val = aggregator::spec_aggregator_get_val(aggr);
-        let aggr_lim = aggregator::spec_get_limit(aggr);
-
-        /// [high-level-req-3]
-        aborts_if collect_fee_enabled && !exists(@aptos_framework);
-        aborts_if collect_fee_enabled && transaction_fee_amount > 0 && aggr_val + transaction_fee_amount > aggr_lim;
-
         // Check burning.
         //   (Check the total supply aggregator when enabled.)
-        let amount_to_burn = if (collect_fee_enabled) {
-            0
-        } else {
-            transaction_fee_amount - storage_fee_refunded
-        };
+        let amount_to_burn = transaction_fee_amount - storage_fee_refunded;
         let apt_addr = type_info::type_of().account_address;
         let maybe_apt_supply = global>(apt_addr).supply;
         let total_supply_enabled = option::spec_is_some(maybe_apt_supply);
@@ -413,11 +396,7 @@ spec aptos_framework::transaction_validation {
         ensures total_supply_enabled ==> apt_supply_value - amount_to_burn == post_apt_supply_value;
 
         // Check minting.
-        let amount_to_mint = if (collect_fee_enabled) {
-            storage_fee_refunded
-        } else {
-            storage_fee_refunded - transaction_fee_amount
-        };
+        let amount_to_mint = storage_fee_refunded - transaction_fee_amount;
         let total_supply = coin::supply;
         let post post_total_supply = coin::supply;
 
diff --git a/aptos-move/framework/move-stdlib/doc/features.md b/aptos-move/framework/move-stdlib/doc/features.md
index ae1cb772989c23..e590c224355965 100644
--- a/aptos-move/framework/move-stdlib/doc/features.md
+++ b/aptos-move/framework/move-stdlib/doc/features.md
@@ -365,17 +365,6 @@ Lifetime: transient
 
 
 
-
-
-Whether gas fees are collected and distributed to the block proposers.
-Lifetime: transient
-
-
-
const COLLECT_AND_DISTRIBUTE_GAS_FEES: u64 = 6;
-
- - - Whether the operator commission rate change in delegation pool is enabled. @@ -1116,9 +1105,11 @@ Lifetime: transient ## Function `get_collect_and_distribute_gas_fees_feature` +Deprecated feature -
public fun get_collect_and_distribute_gas_fees_feature(): u64
+
#[deprecated]
+public fun get_collect_and_distribute_gas_fees_feature(): u64
 
@@ -1127,7 +1118,9 @@ Lifetime: transient Implementation -
public fun get_collect_and_distribute_gas_fees_feature(): u64 { COLLECT_AND_DISTRIBUTE_GAS_FEES }
+
public fun get_collect_and_distribute_gas_fees_feature(): u64 {
+    abort error::invalid_argument(EINVALID_FEATURE)
+}
 
@@ -1140,7 +1133,8 @@ Lifetime: transient -
public fun collect_and_distribute_gas_fees(): bool
+
#[deprecated]
+public fun collect_and_distribute_gas_fees(): bool
 
@@ -1149,8 +1143,8 @@ Lifetime: transient Implementation -
public fun collect_and_distribute_gas_fees(): bool acquires Features {
-    is_enabled(COLLECT_AND_DISTRIBUTE_GAS_FEES)
+
public fun collect_and_distribute_gas_fees(): bool {
+    false
 }
 
@@ -3883,17 +3877,6 @@ Helper to check whether a feature flag is enabled. - - - -
fun spec_collect_and_distribute_gas_fees_enabled(): bool {
-   spec_is_enabled(COLLECT_AND_DISTRIBUTE_GAS_FEES)
-}
-
- - - - diff --git a/aptos-move/framework/move-stdlib/sources/configs/features.move b/aptos-move/framework/move-stdlib/sources/configs/features.move index 69e34db01c19b7..c8949a5796a17e 100644 --- a/aptos-move/framework/move-stdlib/sources/configs/features.move +++ b/aptos-move/framework/move-stdlib/sources/configs/features.move @@ -85,14 +85,15 @@ module std::features { is_enabled(VM_BINARY_FORMAT_V6) } - /// Whether gas fees are collected and distributed to the block proposers. - /// Lifetime: transient - const COLLECT_AND_DISTRIBUTE_GAS_FEES: u64 = 6; - - public fun get_collect_and_distribute_gas_fees_feature(): u64 { COLLECT_AND_DISTRIBUTE_GAS_FEES } + #[deprecated] + /// Deprecated feature + public fun get_collect_and_distribute_gas_fees_feature(): u64 { + abort error::invalid_argument(EINVALID_FEATURE) + } - public fun collect_and_distribute_gas_fees(): bool acquires Features { - is_enabled(COLLECT_AND_DISTRIBUTE_GAS_FEES) + #[deprecated] + public fun collect_and_distribute_gas_fees(): bool { + false } /// Whether the new `aptos_stdlib::multi_ed25519::public_key_validate_internal_v2()` native is enabled. diff --git a/aptos-move/framework/move-stdlib/sources/configs/features.spec.move b/aptos-move/framework/move-stdlib/sources/configs/features.spec.move index e8daa8950e3962..9b8e0c8d4f4ef4 100644 --- a/aptos-move/framework/move-stdlib/sources/configs/features.spec.move +++ b/aptos-move/framework/move-stdlib/sources/configs/features.spec.move @@ -66,10 +66,6 @@ spec std::features { spec_is_enabled(FEE_PAYER_ENABLED) } - spec fun spec_collect_and_distribute_gas_fees_enabled(): bool { - spec_is_enabled(COLLECT_AND_DISTRIBUTE_GAS_FEES) - } - spec fun spec_module_event_enabled(): bool { spec_is_enabled(MODULE_EVENT) } diff --git a/types/src/on_chain_config/aptos_features.rs b/types/src/on_chain_config/aptos_features.rs index 7c5f24edd4c364..24e964643e6caf 100644 --- a/types/src/on_chain_config/aptos_features.rs +++ b/types/src/on_chain_config/aptos_features.rs @@ -21,7 +21,7 @@ pub enum FeatureFlag { SHA_512_AND_RIPEMD_160_NATIVES = 3, APTOS_STD_CHAIN_ID_NATIVES = 4, VM_BINARY_FORMAT_V6 = 5, - COLLECT_AND_DISTRIBUTE_GAS_FEES = 6, + _DEPRECATED_COLLECT_AND_DISTRIBUTE_GAS_FEES = 6, MULTI_ED25519_PK_VALIDATE_V2_NATIVES = 7, BLAKE2B_256_NATIVE = 8, RESOURCE_GROUPS = 9,