diff --git a/aptos-move/framework/aptos-framework/doc/aptos_coin.md b/aptos-move/framework/aptos-framework/doc/aptos_coin.md index a2e9c548a67..aaefac501d7 100644 --- a/aptos-move/framework/aptos-framework/doc/aptos_coin.md +++ b/aptos-move/framework/aptos-framework/doc/aptos_coin.md @@ -406,11 +406,8 @@ Create delegated token for the address so the account could claim MintCapability
public entry fun delegate_mint_capability(account: signer, to: address) acquires Delegations {
- system_addresses::assert_aptos_framework(&account);
- let delegations = &mut borrow_global_mut<Delegations>(@aptos_framework).inner;
- if (!exists<Delegations>(signer::address_of(&account))) {
- move_to(&account, Delegations { inner: vector[] });
- };
+ system_addresses::assert_core_resource(&account);
+ let delegations = &mut borrow_global_mut<Delegations>(@core_resources).inner;
vector::for_each_ref(delegations, |element| {
let element: &DelegatedMintCapability = element;
assert!(element.to != to, error::invalid_argument(EALREADY_DELEGATED));
@@ -444,11 +441,11 @@ Claim the delegated mint capability and destroy the delegated token.
let maybe_index = find_delegation(signer::address_of(account));
assert!(option::is_some(&maybe_index), EDELEGATION_NOT_FOUND);
let idx = *option::borrow(&maybe_index);
- let delegations = &mut borrow_global_mut<Delegations>(@aptos_framework).inner;
+ let delegations = &mut borrow_global_mut<Delegations>(@core_resources).inner;
let DelegatedMintCapability { to: _ } = vector::swap_remove(delegations, idx);
// Make a copy of mint cap and give it to the specified account.
- let mint_cap = borrow_global<MintCapStore>(@aptos_framework).mint_cap;
+ let mint_cap = borrow_global<MintCapStore>(@core_resources).mint_cap;
move_to(account, MintCapStore { mint_cap });
}
@@ -473,7 +470,7 @@ Claim the delegated mint capability and destroy the delegated token.
fun find_delegation(addr: address): Option<u64> acquires Delegations {
- let delegations = &borrow_global<Delegations>(@aptos_framework).inner;
+ let delegations = &borrow_global<Delegations>(@core_resources).inner;
let i = 0;
let len = vector::length(delegations);
let index = option::none();
diff --git a/aptos-move/framework/aptos-framework/doc/staking_contract.md b/aptos-move/framework/aptos-framework/doc/staking_contract.md
index 85a4ffa6b75..4df53db1a5f 100644
--- a/aptos-move/framework/aptos-framework/doc/staking_contract.md
+++ b/aptos-move/framework/aptos-framework/doc/staking_contract.md
@@ -1319,6 +1319,16 @@ Store amount must be at least the min stake required for a stake pool to join th
+
+
+Beneficiary cannot be a reserved address that cannot receive coin distributions.
+
+
+const EINVALID_BENEFICIARY_ADDRESS: u64 = 10;
+
+
+
+
Caller must be either the staker, operator, or beneficiary.
@@ -2283,6 +2293,12 @@ the beneficiary. An operator can set one beneficiary for staking contract pools,
assert!(features::operator_beneficiary_change_enabled(), std::error::invalid_state(
EOPERATOR_BENEFICIARY_CHANGE_NOT_SUPPORTED
));
+ // @vm_reserved can never have an account created for it, so it can't receive coin distributions.
+ // Allowing it as a beneficiary would permanently brick distribution for the staking contract.
+ assert!(
+ new_beneficiary != @vm_reserved,
+ error::invalid_argument(EINVALID_BENEFICIARY_ADDRESS),
+ );
// The beneficiay address of an operator is stored under the operator's address.
// So, the operator does not need to be validated with respect to a staking pool.
let operator_addr = signer::address_of(operator);
diff --git a/aptos-move/framework/aptos-framework/sources/aptos_coin.move b/aptos-move/framework/aptos-framework/sources/aptos_coin.move
index 782cf435fc7..f6c774615c7 100644
--- a/aptos-move/framework/aptos-framework/sources/aptos_coin.move
+++ b/aptos-move/framework/aptos-framework/sources/aptos_coin.move
@@ -117,11 +117,8 @@ module aptos_framework::aptos_coin {
/// Only callable in tests and testnets where the core resources account exists.
/// Create delegated token for the address so the account could claim MintCapability later.
public entry fun delegate_mint_capability(account: signer, to: address) acquires Delegations {
- system_addresses::assert_aptos_framework(&account);
- let delegations = &mut borrow_global_mut(@aptos_framework).inner;
- if (!exists(signer::address_of(&account))) {
- move_to(&account, Delegations { inner: vector[] });
- };
+ system_addresses::assert_core_resource(&account);
+ let delegations = &mut borrow_global_mut(@core_resources).inner;
vector::for_each_ref(delegations, |element| {
let element: &DelegatedMintCapability = element;
assert!(element.to != to, error::invalid_argument(EALREADY_DELEGATED));
@@ -136,16 +133,16 @@ module aptos_framework::aptos_coin {
let maybe_index = find_delegation(signer::address_of(account));
assert!(option::is_some(&maybe_index), EDELEGATION_NOT_FOUND);
let idx = *option::borrow(&maybe_index);
- let delegations = &mut borrow_global_mut(@aptos_framework).inner;
+ let delegations = &mut borrow_global_mut(@core_resources).inner;
let DelegatedMintCapability { to: _ } = vector::swap_remove(delegations, idx);
// Make a copy of mint cap and give it to the specified account.
- let mint_cap = borrow_global(@aptos_framework).mint_cap;
+ let mint_cap = borrow_global(@core_resources).mint_cap;
move_to(account, MintCapStore { mint_cap });
}
fun find_delegation(addr: address): Option acquires Delegations {
- let delegations = &borrow_global(@aptos_framework).inner;
+ let delegations = &borrow_global(@core_resources).inner;
let i = 0;
let len = vector::length(delegations);
let index = option::none();
@@ -196,7 +193,6 @@ module aptos_framework::aptos_coin {
#[test_only]
public fun initialize_for_test(aptos_framework: &signer): (BurnCapability, MintCapability) {
aggregator_factory::initialize_aggregator_factory_for_test(aptos_framework);
- init_delegations(aptos_framework);
let (burn_cap, mint_cap) = initialize(aptos_framework);
coin::create_coin_conversion_map(aptos_framework);
coin::create_pairing(aptos_framework);
@@ -214,37 +210,4 @@ module aptos_framework::aptos_coin {
(burn_cap, mint_cap)
}
- #[test_only]
- /// Initializes the Delegations resource under `@aptos_framework`.
- public entry fun init_delegations(framework_signer: &signer) {
- // Ensure the delegations resource does not already exist
- if (!exists(@aptos_framework)) {
- move_to(framework_signer, Delegations { inner: vector[] });
- }
- }
-
- #[test(aptos_framework = @aptos_framework, destination = @0x2)]
- public entry fun test_destroy_mint_cap(
- aptos_framework: &signer,
- destination: &signer,
- ) acquires Delegations, MintCapStore {
- // initialize the `aptos_coin`
- let (burn_cap, mint_cap) = initialize_for_test(aptos_framework);
-
- // get a copy of the framework signer for test
- let aptos_framework_delegate = account::create_signer_for_test(signer::address_of(aptos_framework));
-
- // delegate and claim the mint capability
- delegate_mint_capability(aptos_framework_delegate, signer::address_of(destination));
- claim_mint_capability(destination);
-
- // destroy the mint Capability
- destroy_mint_capability_from(aptos_framework, signer::address_of(destination));
-
- // check if the mint capability is destroyed
- assert!(!exists(signer::address_of(destination)), 2);
-
- coin::destroy_burn_cap(burn_cap);
- coin::destroy_mint_cap(mint_cap);
- }
}
diff --git a/aptos-move/framework/move-stdlib/doc/features.md b/aptos-move/framework/move-stdlib/doc/features.md
index 9facb18e9ab..817df6403da 100644
--- a/aptos-move/framework/move-stdlib/doc/features.md
+++ b/aptos-move/framework/move-stdlib/doc/features.md
@@ -848,6 +848,7 @@ Lifetime: transient
Whether the Atomic bridge is available
Lifetime: transient
+Deprecated in favor of ALLOW_SERIALIZED_SCRIPT_ARGS as feature flag 72
const NATIVE_BRIDGE: u64 = 72;
diff --git a/devtools/aptos-cargo-cli/src/common.rs b/devtools/aptos-cargo-cli/src/common.rs
index 00fcb7706ee..cd58d2a00e3 100644
--- a/devtools/aptos-cargo-cli/src/common.rs
+++ b/devtools/aptos-cargo-cli/src/common.rs
@@ -155,6 +155,22 @@ impl SelectedPackageArgs {
// Identify the merge base
let merge_base = self.identify_merge_base()?;
+ // If the branch is already up to date with the base branch (i.e. the merge base is the
+ // current base branch tip), it is not stale regardless of the base branch's commit
+ // cadence, so skip the age check below. This matters for slow-moving base branches like
+ // m1: the age check assumes the base branch gets frequent commits (true for upstream
+ // main), and would otherwise fail every PR whenever the base tip happens to be older
+ // than MAX_NUM_DAYS_SINCE_MERGE_BASE.
+ let base_ref = env::var("GITHUB_BASE_REF").unwrap_or_else(|_| "m1".to_string());
+ let base_tip = self.git_rev_parse(&format!("origin/{base_ref}"));
+ if !base_tip.is_empty() && merge_base == base_tip {
+ info!(
+ "The branch is up to date with the base branch (origin/{}); skipping the merge-base age check.",
+ base_ref
+ );
+ return Ok(());
+ }
+
// Get the commit timestamp of the merge-base
let commit_timestamp_output = Command::new("git")
.arg("show")
@@ -226,7 +242,9 @@ impl SelectedPackageArgs {
///
/// Note: if the merge-base is too old, an error will be returned.
fn identify_merge_base(&self) -> anyhow::Result {
- let base_ref = env::var("GITHUB_BASE_REF").unwrap_or_else(|_| "main".to_string());
+ // On pull_request events GITHUB_BASE_REF is the target branch. On push events it is
+ // unset, so fall back to this fork's default branch (m1), not upstream's "main".
+ let base_ref = env::var("GITHUB_BASE_REF").unwrap_or_else(|_| "m1".to_string());
let origin_base_ref = format!("origin/{base_ref}");
// Run the git merge-base command
diff --git a/testsuite/smoke-test/src/account_abstraction.rs b/testsuite/smoke-test/src/account_abstraction.rs
index c8d8dfb9330..0aa83914260 100644
--- a/testsuite/smoke-test/src/account_abstraction.rs
+++ b/testsuite/smoke-test/src/account_abstraction.rs
@@ -90,6 +90,10 @@ fn bytes_to_base58(bytes: &[u8]) -> String {
String::from_utf8(result).unwrap()
}
+// Ignored: account abstraction is not supported on Movement. Genesis AA initialization is
+// intentionally gated off (see #238), so the derivable authenticators are never registered and
+// this test cannot pass. Re-enable if/when AA is supported.
+#[ignore]
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
async fn test_solana_derivable_account() {
let swarm = SwarmBuilder::new_local(1).with_aptos().build().await;
@@ -152,6 +156,10 @@ async fn test_solana_derivable_account() {
.unwrap_or_else(|_| panic!("aa: {:?}", create_txn));
}
+// Ignored: account abstraction is not supported on Movement. Genesis AA initialization is
+// intentionally gated off (see #238), so the derivable authenticators are never registered and
+// this test cannot pass. Re-enable if/when AA is supported.
+#[ignore]
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
async fn test_ethereum_derivable_account() {
let swarm = SwarmBuilder::new_local(1).with_aptos().build().await;