diff --git a/aptos-move/framework/aptos-token-objects/doc/collection.md b/aptos-move/framework/aptos-token-objects/doc/collection.md
index 8c992d2badc36..59b704ea47bc0 100644
--- a/aptos-move/framework/aptos-token-objects/doc/collection.md
+++ b/aptos-move/framework/aptos-token-objects/doc/collection.md
@@ -980,9 +980,6 @@ TODO: Hide this until we bring back meaningful way to enforce burns
royalty::init(&constructor_ref, option::extract(&mut royalty))
};
- let transfer_ref = object::generate_transfer_ref(&constructor_ref);
- object::disable_ungated_transfer(&transfer_ref);
-
constructor_ref
}
diff --git a/aptos-move/framework/aptos-token-objects/doc/token.md b/aptos-move/framework/aptos-token-objects/doc/token.md
index b4c53eb85ef63..0068cdeaf002b 100644
--- a/aptos-move/framework/aptos-token-objects/doc/token.md
+++ b/aptos-move/framework/aptos-token-objects/doc/token.md
@@ -380,6 +380,16 @@ The URI is over the maximum length
+
+
+The calling signer is not the owner
+
+
+
const ENOT_OWNER: u64 = 8;
+
+
+
+
The description is over the maximum length
@@ -542,7 +552,7 @@ The token name is over the maximum length
royalty: Option<Royalty>,
uri: String,
) {
- assert!(collection::creator(collection) == signer::address_of(creator), error::unauthenticated(ENOT_CREATOR));
+ assert!(object::owner(collection) == signer::address_of(creator), error::unauthenticated(ENOT_OWNER));
if (option::is_some(&name_with_index_suffix)) {
// Be conservative, as we don't know what length the index will be, and assume worst case (20 chars in MAX_U64)
diff --git a/aptos-move/framework/aptos-token-objects/sources/collection.move b/aptos-move/framework/aptos-token-objects/sources/collection.move
index b3adbf6f3bc6a..af88007f84dfa 100644
--- a/aptos-move/framework/aptos-token-objects/sources/collection.move
+++ b/aptos-move/framework/aptos-token-objects/sources/collection.move
@@ -296,9 +296,6 @@ module aptos_token_objects::collection {
royalty::init(&constructor_ref, option::extract(&mut royalty))
};
- let transfer_ref = object::generate_transfer_ref(&constructor_ref);
- object::disable_ungated_transfer(&transfer_ref);
-
constructor_ref
}
@@ -750,9 +747,9 @@ module aptos_token_objects::collection {
}
#[test(creator = @0x123, trader = @0x456)]
- #[expected_failure(abort_code = 0x50003, location = aptos_framework::object)]
entry fun test_create_and_transfer(creator: &signer, trader: &signer) {
let creator_address = signer::address_of(creator);
+ let trader_address = signer::address_of(trader);
let collection_name = string::utf8(b"collection name");
create_collection_helper(creator, collection_name);
@@ -760,7 +757,9 @@ module aptos_token_objects::collection {
create_collection_address(&creator_address, &collection_name),
);
assert!(object::owner(collection) == creator_address, 1);
- object::transfer(creator, collection, signer::address_of(trader));
+ // Transferring collections is allowed
+ object::transfer(creator, collection, trader_address);
+ assert!(object::owner(collection) == trader_address, 1);
}
#[test(creator = @0x123)]
diff --git a/aptos-move/framework/aptos-token-objects/sources/token.move b/aptos-move/framework/aptos-token-objects/sources/token.move
index 0d944c99c5cfc..4187f5306393e 100644
--- a/aptos-move/framework/aptos-token-objects/sources/token.move
+++ b/aptos-move/framework/aptos-token-objects/sources/token.move
@@ -33,6 +33,8 @@ module aptos_token_objects::token {
const EDESCRIPTION_TOO_LONG: u64 = 6;
/// The seed is over the maximum length
const ESEED_TOO_LONG: u64 = 7;
+ /// The calling signer is not the owner
+ const ENOT_OWNER: u64 = 8;
const MAX_TOKEN_NAME_LENGTH: u64 = 128;
const MAX_TOKEN_SEED_LENGTH: u64 = 128;
@@ -154,7 +156,7 @@ module aptos_token_objects::token {
royalty: Option,
uri: String,
) {
- assert!(collection::creator(collection) == signer::address_of(creator), error::unauthenticated(ENOT_CREATOR));
+ assert!(object::owner(collection) == signer::address_of(creator), error::unauthenticated(ENOT_OWNER));
if (option::is_some(&name_with_index_suffix)) {
// Be conservative, as we don't know what length the index will be, and assume worst case (20 chars in MAX_U64)
@@ -722,8 +724,8 @@ module aptos_token_objects::token {
}
#[test(creator = @0x123, trader = @0x456)]
- #[expected_failure(abort_code = 0x40002, location = aptos_token_objects::token)]
- fun test_create_token_non_creator(creator: &signer, trader: &signer) {
+ #[expected_failure(abort_code = 0x40008, location = aptos_token_objects::token)]
+ fun test_create_token_non_collection_owner(creator: &signer, trader: &signer) {
let constructor_ref = &create_fixed_collection(creator, string::utf8(b"collection name"), 5);
let collection = get_collection_from_ref(&object::generate_extend_ref(constructor_ref));
create_token(
@@ -733,16 +735,16 @@ module aptos_token_objects::token {
}
#[test(creator = @0x123, trader = @0x456)]
- #[expected_failure(abort_code = 0x40002, location = aptos_token_objects::token)]
- fun test_create_named_token_non_creator(creator: &signer, trader: &signer) {
+ #[expected_failure(abort_code = 0x40008, location = aptos_token_objects::token)]
+ fun test_create_named_token_non_collection_owner(creator: &signer, trader: &signer) {
let constructor_ref = &create_fixed_collection(creator, string::utf8(b"collection name"), 5);
let collection = get_collection_from_ref(&object::generate_extend_ref(constructor_ref));
create_token_with_collection_helper(trader, collection, string::utf8(b"token name"));
}
#[test(creator = @0x123, trader = @0x456)]
- #[expected_failure(abort_code = 0x40002, location = aptos_token_objects::token)]
- fun test_create_named_token_object_non_creator(creator: &signer, trader: &signer) {
+ #[expected_failure(abort_code = 0x40008, location = aptos_token_objects::token)]
+ fun test_create_named_token_object_non_collection_owner(creator: &signer, trader: &signer) {
let constructor_ref = &create_fixed_collection(creator, string::utf8(b"collection name"), 5);
let collection = get_collection_from_ref(&object::generate_extend_ref(constructor_ref));
create_named_token_object(
@@ -752,8 +754,8 @@ module aptos_token_objects::token {
}
#[test(creator = @0x123, trader = @0x456)]
- #[expected_failure(abort_code = 0x40002, location = aptos_token_objects::token)]
- fun test_create_named_token_from_seed_non_creator(creator: &signer, trader: &signer) {
+ #[expected_failure(abort_code = 0x40008, location = aptos_token_objects::token)]
+ fun test_create_named_token_from_seed_non_collection_owner(creator: &signer, trader: &signer) {
let constructor_ref = &create_fixed_collection(creator, string::utf8(b"collection name"), 5);
let collection = get_collection_from_ref(&object::generate_extend_ref(constructor_ref));
create_named_token_object(
@@ -784,6 +786,43 @@ module aptos_token_objects::token {
assert!(option::some(expected_royalty) == royalty(token), 2);
}
+ #[test(creator = @0x123, trader = @0x456)]
+ #[expected_failure(abort_code = 0x40008, location = aptos_token_objects::token)]
+ fun test_create_token_after_transferring_collection(creator: &signer, trader: &signer) {
+ let constructor_ref = &create_fixed_collection(creator, string::utf8(b"collection name"), 5);
+ let collection = get_collection_from_ref(&object::generate_extend_ref(constructor_ref));
+ create_token(
+ creator, collection, string::utf8(b"token description"), string::utf8(b"token name"),
+ option::some(royalty::create(25, 10000, signer::address_of(creator))), string::utf8(b"uri"),
+ );
+
+ object::transfer(creator, collection, signer::address_of(trader));
+
+ // This should fail as the collection is no longer owned by the creator.
+ create_token(
+ creator, collection, string::utf8(b"token description"), string::utf8(b"token name"),
+ option::some(royalty::create(25, 10000, signer::address_of(creator))), string::utf8(b"uri"),
+ );
+ }
+
+ #[test(creator = @0x123, trader = @0x456)]
+ fun create_token_works_with_new_collection_owner(creator: &signer, trader: &signer) {
+ let constructor_ref = &create_fixed_collection(creator, string::utf8(b"collection name"), 5);
+ let collection = get_collection_from_ref(&object::generate_extend_ref(constructor_ref));
+ create_token(
+ creator, collection, string::utf8(b"token description"), string::utf8(b"token name"),
+ option::some(royalty::create(25, 10000, signer::address_of(creator))), string::utf8(b"uri"),
+ );
+
+ object::transfer(creator, collection, signer::address_of(trader));
+
+ // This should pass as `trader` is the new collection owner
+ create_token(
+ trader, collection, string::utf8(b"token description"), string::utf8(b"token name"),
+ option::some(royalty::create(25, 10000, signer::address_of(creator))), string::utf8(b"uri"),
+ );
+ }
+
#[test(creator = @0x123)]
fun test_collection_royalty(creator: &signer) acquires Token {
let collection_name = string::utf8(b"collection name");