Skip to content

Commit

Permalink
[Aptos Framework][Object] Update transfer_with_ref to remove tombston…
Browse files Browse the repository at this point in the history
…e if present (#13495)
  • Loading branch information
movekevin authored May 31, 2024
1 parent 702abf4 commit e8c5e4b
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 6 deletions.
8 changes: 7 additions & 1 deletion aptos-move/framework/aptos-framework/doc/object.md
Original file line number Diff line number Diff line change
Expand Up @@ -1866,8 +1866,14 @@ Transfer to the destination address using a LinearTransferRef.
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="object.md#0x1_object_transfer_with_ref">transfer_with_ref</a>(ref: <a href="object.md#0x1_object_LinearTransferRef">LinearTransferRef</a>, <b>to</b>: <b>address</b>) <b>acquires</b> <a href="object.md#0x1_object_ObjectCore">ObjectCore</a> {
<pre><code><b>public</b> <b>fun</b> <a href="object.md#0x1_object_transfer_with_ref">transfer_with_ref</a>(ref: <a href="object.md#0x1_object_LinearTransferRef">LinearTransferRef</a>, <b>to</b>: <b>address</b>) <b>acquires</b> <a href="object.md#0x1_object_ObjectCore">ObjectCore</a>, <a href="object.md#0x1_object_TombStone">TombStone</a> {
<b>assert</b>!(!<b>exists</b>&lt;<a href="object.md#0x1_object_Untransferable">Untransferable</a>&gt;(ref.self), <a href="../../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_permission_denied">error::permission_denied</a>(<a href="object.md#0x1_object_ENOT_MOVABLE">ENOT_MOVABLE</a>));

// Undo soft burn <b>if</b> present <b>as</b> we don't want the original owner <b>to</b> be able <b>to</b> reclaim by calling unburn later.
<b>if</b> (<b>exists</b>&lt;<a href="object.md#0x1_object_TombStone">TombStone</a>&gt;(ref.self)) {
<b>let</b> <a href="object.md#0x1_object_TombStone">TombStone</a> { original_owner: _ } = <b>move_from</b>&lt;<a href="object.md#0x1_object_TombStone">TombStone</a>&gt;(ref.self);
};

<b>let</b> <a href="object.md#0x1_object">object</a> = <b>borrow_global_mut</b>&lt;<a href="object.md#0x1_object_ObjectCore">ObjectCore</a>&gt;(ref.self);
<b>assert</b>!(
<a href="object.md#0x1_object">object</a>.owner == ref.owner,
Expand Down
26 changes: 21 additions & 5 deletions aptos-move/framework/aptos-framework/sources/object.move
Original file line number Diff line number Diff line change
Expand Up @@ -475,8 +475,14 @@ module aptos_framework::object {
}

/// Transfer to the destination address using a LinearTransferRef.
public fun transfer_with_ref(ref: LinearTransferRef, to: address) acquires ObjectCore {
public fun transfer_with_ref(ref: LinearTransferRef, to: address) acquires ObjectCore, TombStone {
assert!(!exists<Untransferable>(ref.self), error::permission_denied(ENOT_MOVABLE));

// Undo soft burn if present as we don't want the original owner to be able to reclaim by calling unburn later.
if (exists<TombStone>(ref.self)) {
let TombStone { original_owner: _ } = move_from<TombStone>(ref.self);
};

let object = borrow_global_mut<ObjectCore>(ref.self);
assert!(
object.owner == ref.owner,
Expand Down Expand Up @@ -785,7 +791,7 @@ module aptos_framework::object {
}

#[test(creator = @0x123)]
fun test_linear_transfer(creator: &signer) acquires ObjectCore {
fun test_linear_transfer(creator: &signer) acquires ObjectCore, TombStone {
let (hero_constructor, hero) = create_hero(creator);
assert!(root_owner(hero) == @0x123, 0);

Expand All @@ -799,7 +805,7 @@ module aptos_framework::object {

#[test(creator = @0x123)]
#[expected_failure(abort_code = 0x50004, location = Self)]
fun test_bad_linear_transfer(creator: &signer) acquires ObjectCore {
fun test_bad_linear_transfer(creator: &signer) acquires ObjectCore, TombStone {
let (hero_constructor, hero) = create_hero(creator);
let transfer_ref = generate_transfer_ref(&hero_constructor);
let linear_transfer_ref_good = generate_linear_transfer_ref(&transfer_ref);
Expand All @@ -810,6 +816,16 @@ module aptos_framework::object {
transfer_with_ref(linear_transfer_ref_bad, @0x789);
}

#[test(creator = @0x123)]
#[expected_failure(abort_code = 0x10008, location = Self)]
fun test_cannot_unburn_after_transfer_with_ref(creator: &signer) acquires ObjectCore, TombStone {
let (hero_constructor, hero) = create_hero(creator);
burn(creator, hero);
let transfer_ref = generate_transfer_ref(&hero_constructor);
transfer_with_ref(generate_linear_transfer_ref(&transfer_ref), @0x456);
unburn(creator, hero);
}

#[test(fx = @std)]
fun test_correct_auid(fx: signer) {
use std::features;
Expand Down Expand Up @@ -1008,7 +1024,7 @@ module aptos_framework::object {

#[test(creator = @0x123)]
#[expected_failure(abort_code = 327689, location = Self)]
fun test_untransferable_direct_ownership_with_linear_transfer_ref(creator: &signer) acquires ObjectCore {
fun test_untransferable_direct_ownership_with_linear_transfer_ref(creator: &signer) acquires ObjectCore, TombStone {
let (hero_constructor_ref, _) = create_hero(creator);
let transfer_ref = generate_transfer_ref(&hero_constructor_ref);
let linear_transfer_ref = generate_linear_transfer_ref(&transfer_ref);
Expand Down Expand Up @@ -1049,7 +1065,7 @@ module aptos_framework::object {

#[test(creator = @0x123)]
#[expected_failure(abort_code = 327689, location = Self)]
fun test_untransferable_indirect_ownership_with_linear_transfer_ref(creator: &signer) acquires ObjectCore {
fun test_untransferable_indirect_ownership_with_linear_transfer_ref(creator: &signer) acquires ObjectCore, TombStone {
let (_, hero) = create_hero(creator);
let (weapon_constructor_ref, weapon) = create_weapon(creator);
transfer_to_object(creator, weapon, hero);
Expand Down

0 comments on commit e8c5e4b

Please sign in to comment.