Skip to content

Commit

Permalink
[object] refactor burn/unburn (aptos-labs#9785)
Browse files Browse the repository at this point in the history
  • Loading branch information
lightmark authored and Poytr1 committed Oct 4, 2023
1 parent 46f1944 commit 3be24c0
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 76 deletions.
76 changes: 38 additions & 38 deletions aptos-move/framework/aptos-framework/doc/object.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ make it so that a reference to a global object can be returned from a function.
- [Function `transfer_call`](#0x1_object_transfer_call)
- [Function `transfer`](#0x1_object_transfer)
- [Function `transfer_raw`](#0x1_object_transfer_raw)
- [Function `transfer_raw_inner`](#0x1_object_transfer_raw_inner)
- [Function `transfer_to_object`](#0x1_object_transfer_to_object)
- [Function `verify_ungated_and_descendant`](#0x1_object_verify_ungated_and_descendant)
- [Function `burn`](#0x1_object_burn)
Expand Down Expand Up @@ -1736,21 +1737,42 @@ hierarchy.
) <b>acquires</b> <a href="object.md#0x1_object_ObjectCore">ObjectCore</a> {
<b>let</b> owner_address = <a href="../../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer_address_of">signer::address_of</a>(owner);
<a href="object.md#0x1_object_verify_ungated_and_descendant">verify_ungated_and_descendant</a>(owner_address, <a href="object.md#0x1_object">object</a>);
<a href="object.md#0x1_object_transfer_raw_inner">transfer_raw_inner</a>(<a href="object.md#0x1_object">object</a>, <b>to</b>);
}
</code></pre>



</details>

<a name="0x1_object_transfer_raw_inner"></a>

## Function `transfer_raw_inner`



<pre><code><b>fun</b> <a href="object.md#0x1_object_transfer_raw_inner">transfer_raw_inner</a>(<a href="object.md#0x1_object">object</a>: <b>address</b>, <b>to</b>: <b>address</b>)
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code>inline <b>fun</b> <a href="object.md#0x1_object_transfer_raw_inner">transfer_raw_inner</a>(<a href="object.md#0x1_object">object</a>: <b>address</b>, <b>to</b>: <b>address</b>) <b>acquires</b> <a href="object.md#0x1_object_ObjectCore">ObjectCore</a> {
<b>let</b> object_core = <b>borrow_global_mut</b>&lt;<a href="object.md#0x1_object_ObjectCore">ObjectCore</a>&gt;(<a href="object.md#0x1_object">object</a>);
<b>if</b> (object_core.owner == <b>to</b>) {
<b>return</b>
<b>if</b> (object_core.owner != <b>to</b>) {
<a href="event.md#0x1_event_emit_event">event::emit_event</a>(
&<b>mut</b> object_core.transfer_events,
<a href="object.md#0x1_object_TransferEvent">TransferEvent</a> {
<a href="object.md#0x1_object">object</a>,
from: object_core.owner,
<b>to</b>,
},
);
object_core.owner = <b>to</b>;
};

<a href="event.md#0x1_event_emit_event">event::emit_event</a>(
&<b>mut</b> object_core.transfer_events,
<a href="object.md#0x1_object_TransferEvent">TransferEvent</a> {
<a href="object.md#0x1_object">object</a>: <a href="object.md#0x1_object">object</a>,
from: object_core.owner,
<b>to</b>,
},
);
object_core.owner = <b>to</b>;
}
</code></pre>

Expand Down Expand Up @@ -1866,21 +1888,10 @@ Original owners can reclaim burnt objects any time in the future by calling unbu

<pre><code><b>public</b> entry <b>fun</b> <a href="object.md#0x1_object_burn">burn</a>&lt;T: key&gt;(owner: &<a href="../../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>, <a href="object.md#0x1_object">object</a>: <a href="object.md#0x1_object_Object">Object</a>&lt;T&gt;) <b>acquires</b> <a href="object.md#0x1_object_ObjectCore">ObjectCore</a> {
<b>let</b> original_owner = <a href="../../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer_address_of">signer::address_of</a>(owner);
<b>assert</b>!(<a href="object.md#0x1_object_owner">owner</a>(<a href="object.md#0x1_object">object</a>) == original_owner, <a href="../../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_permission_denied">error::permission_denied</a>(<a href="object.md#0x1_object_ENOT_OBJECT_OWNER">ENOT_OBJECT_OWNER</a>));
<b>assert</b>!(<a href="object.md#0x1_object_is_owner">is_owner</a>(<a href="object.md#0x1_object">object</a>, original_owner), <a href="../../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_permission_denied">error::permission_denied</a>(<a href="object.md#0x1_object_ENOT_OBJECT_OWNER">ENOT_OBJECT_OWNER</a>));
<b>let</b> object_addr = <a href="object.md#0x1_object">object</a>.inner;
<b>move_to</b>(&<a href="create_signer.md#0x1_create_signer">create_signer</a>(object_addr), <a href="object.md#0x1_object_TombStone">TombStone</a> { original_owner });
<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;(object_addr);
<a href="object.md#0x1_object">object</a>.owner = <a href="object.md#0x1_object_BURN_ADDRESS">BURN_ADDRESS</a>;

// Burn should still emit <a href="event.md#0x1_event">event</a> <b>to</b> make sure ownership is upgrade correctly in indexing.
<a href="event.md#0x1_event_emit_event">event::emit_event</a>(
&<b>mut</b> <a href="object.md#0x1_object">object</a>.transfer_events,
<a href="object.md#0x1_object_TransferEvent">TransferEvent</a> {
<a href="object.md#0x1_object">object</a>: object_addr,
from: original_owner,
<b>to</b>: <a href="object.md#0x1_object_BURN_ADDRESS">BURN_ADDRESS</a>,
},
);
<a href="object.md#0x1_object_transfer_raw_inner">transfer_raw_inner</a>(object_addr, <a href="object.md#0x1_object_BURN_ADDRESS">BURN_ADDRESS</a>);
}
</code></pre>

Expand All @@ -1907,24 +1918,13 @@ Allow origin owners to reclaim any objects they previous burnt.
<pre><code><b>public</b> entry <b>fun</b> <a href="object.md#0x1_object_unburn">unburn</a>&lt;T: key&gt;(
original_owner: &<a href="../../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer">signer</a>,
<a href="object.md#0x1_object">object</a>: <a href="object.md#0x1_object_Object">Object</a>&lt;T&gt;,
) <b>acquires</b> <a href="object.md#0x1_object_ObjectCore">ObjectCore</a>, <a href="object.md#0x1_object_TombStone">TombStone</a> {
) <b>acquires</b> <a href="object.md#0x1_object_TombStone">TombStone</a>, <a href="object.md#0x1_object_ObjectCore">ObjectCore</a> {
<b>let</b> object_addr = <a href="object.md#0x1_object">object</a>.inner;
<b>assert</b>!(<b>exists</b>&lt;<a href="object.md#0x1_object_TombStone">TombStone</a>&gt;(object_addr), <a href="../../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_invalid_argument">error::invalid_argument</a>(<a href="object.md#0x1_object_EOBJECT_NOT_BURNT">EOBJECT_NOT_BURNT</a>));

<b>let</b> <a href="object.md#0x1_object_TombStone">TombStone</a> { original_owner: original_owner_addr } = <b>move_from</b>&lt;<a href="object.md#0x1_object_TombStone">TombStone</a>&gt;(object_addr);
<b>assert</b>!(original_owner_addr == <a href="../../aptos-stdlib/../move-stdlib/doc/signer.md#0x1_signer_address_of">signer::address_of</a>(original_owner), <a href="../../aptos-stdlib/../move-stdlib/doc/error.md#0x1_error_permission_denied">error::permission_denied</a>(<a href="object.md#0x1_object_ENOT_OBJECT_OWNER">ENOT_OBJECT_OWNER</a>));
<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;(object_addr);
<a href="object.md#0x1_object">object</a>.owner = original_owner_addr;

// Unburn reclaims should still emit <a href="event.md#0x1_event">event</a> <b>to</b> make sure ownership is upgrade correctly in indexing.
<a href="event.md#0x1_event_emit_event">event::emit_event</a>(
&<b>mut</b> <a href="object.md#0x1_object">object</a>.transfer_events,
<a href="object.md#0x1_object_TransferEvent">TransferEvent</a> {
<a href="object.md#0x1_object">object</a>: object_addr,
from: <a href="object.md#0x1_object_BURN_ADDRESS">BURN_ADDRESS</a>,
<b>to</b>: original_owner_addr,
},
);
<a href="object.md#0x1_object_transfer_raw_inner">transfer_raw_inner</a>(object_addr, original_owner_addr);
}
</code></pre>

Expand Down
55 changes: 17 additions & 38 deletions aptos-move/framework/aptos-framework/sources/object.move
Original file line number Diff line number Diff line change
Expand Up @@ -467,21 +467,22 @@ module aptos_framework::object {
) acquires ObjectCore {
let owner_address = signer::address_of(owner);
verify_ungated_and_descendant(owner_address, object);
transfer_raw_inner(object, to);
}

inline fun transfer_raw_inner(object: address, to: address) acquires ObjectCore {
let object_core = borrow_global_mut<ObjectCore>(object);
if (object_core.owner == to) {
return
if (object_core.owner != to) {
event::emit_event(
&mut object_core.transfer_events,
TransferEvent {
object,
from: object_core.owner,
to,
},
);
object_core.owner = to;
};

event::emit_event(
&mut object_core.transfer_events,
TransferEvent {
object: object,
from: object_core.owner,
to,
},
);
object_core.owner = to;
}

/// Transfer the given object to another object. See `transfer` for more information.
Expand Down Expand Up @@ -537,45 +538,23 @@ module aptos_framework::object {
/// Original owners can reclaim burnt objects any time in the future by calling unburn.
public entry fun burn<T: key>(owner: &signer, object: Object<T>) acquires ObjectCore {
let original_owner = signer::address_of(owner);
assert!(owner(object) == original_owner, error::permission_denied(ENOT_OBJECT_OWNER));
assert!(is_owner(object, original_owner), error::permission_denied(ENOT_OBJECT_OWNER));
let object_addr = object.inner;
move_to(&create_signer(object_addr), TombStone { original_owner });
let object = borrow_global_mut<ObjectCore>(object_addr);
object.owner = BURN_ADDRESS;

// Burn should still emit event to make sure ownership is upgrade correctly in indexing.
event::emit_event(
&mut object.transfer_events,
TransferEvent {
object: object_addr,
from: original_owner,
to: BURN_ADDRESS,
},
);
transfer_raw_inner(object_addr, BURN_ADDRESS);
}

/// Allow origin owners to reclaim any objects they previous burnt.
public entry fun unburn<T: key>(
original_owner: &signer,
object: Object<T>,
) acquires ObjectCore, TombStone {
) acquires TombStone, ObjectCore {
let object_addr = object.inner;
assert!(exists<TombStone>(object_addr), error::invalid_argument(EOBJECT_NOT_BURNT));

let TombStone { original_owner: original_owner_addr } = move_from<TombStone>(object_addr);
assert!(original_owner_addr == signer::address_of(original_owner), error::permission_denied(ENOT_OBJECT_OWNER));
let object = borrow_global_mut<ObjectCore>(object_addr);
object.owner = original_owner_addr;

// Unburn reclaims should still emit event to make sure ownership is upgrade correctly in indexing.
event::emit_event(
&mut object.transfer_events,
TransferEvent {
object: object_addr,
from: BURN_ADDRESS,
to: original_owner_addr,
},
);
transfer_raw_inner(object_addr, original_owner_addr);
}

/// Accessors
Expand Down

0 comments on commit 3be24c0

Please sign in to comment.