Skip to content

Commit

Permalink
stablecoin deposit/withdraw hook fix (#13603)
Browse files Browse the repository at this point in the history
* stablecoin deposit/withdraw hook fix

* add inline functions to pfs module

* inline function for pfs address

* add comments

* fix build issues

* fix rust lints
  • Loading branch information
kshitjee authored Jun 12, 2024
1 parent 097921e commit 5ad91bc
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 2 deletions.
83 changes: 83 additions & 0 deletions aptos-move/framework/aptos-framework/doc/primary_fungible_store.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ fungible asset to it. This emits an deposit event.
- [Function `primary_store_address`](#0x1_primary_fungible_store_primary_store_address)
- [Function `primary_store`](#0x1_primary_fungible_store_primary_store)
- [Function `primary_store_exists`](#0x1_primary_fungible_store_primary_store_exists)
- [Function `primary_store_address_inlined`](#0x1_primary_fungible_store_primary_store_address_inlined)
- [Function `primary_store_inlined`](#0x1_primary_fungible_store_primary_store_inlined)
- [Function `primary_store_exists_inlined`](#0x1_primary_fungible_store_primary_store_exists_inlined)
- [Function `balance`](#0x1_primary_fungible_store_balance)
- [Function `is_balance_at_least`](#0x1_primary_fungible_store_is_balance_at_least)
- [Function `is_frozen`](#0x1_primary_fungible_store_is_frozen)
Expand Down Expand Up @@ -280,6 +283,86 @@ Return whether the given account's primary store exists.



</details>

<a id="0x1_primary_fungible_store_primary_store_address_inlined"></a>

## Function `primary_store_address_inlined`

Get the address of the primary store for the given account.
Use instead of the corresponding view functions for dispatchable hooks to avoid circular dependencies of modules.


<pre><code><b>public</b> <b>fun</b> <a href="primary_fungible_store.md#0x1_primary_fungible_store_primary_store_address_inlined">primary_store_address_inlined</a>&lt;T: key&gt;(owner: <b>address</b>, metadata: <a href="object.md#0x1_object_Object">object::Object</a>&lt;T&gt;): <b>address</b>
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b> inline <b>fun</b> <a href="primary_fungible_store.md#0x1_primary_fungible_store_primary_store_address_inlined">primary_store_address_inlined</a>&lt;T: key&gt;(owner: <b>address</b>, metadata: Object&lt;T&gt;): <b>address</b> {
<b>let</b> metadata_addr = <a href="object.md#0x1_object_object_address">object::object_address</a>(&metadata);
<a href="object.md#0x1_object_create_user_derived_object_address">object::create_user_derived_object_address</a>(owner, metadata_addr)
}
</code></pre>



</details>

<a id="0x1_primary_fungible_store_primary_store_inlined"></a>

## Function `primary_store_inlined`

Get the primary store object for the given account.
Use instead of the corresponding view functions for dispatchable hooks to avoid circular dependencies of modules.


<pre><code><b>public</b> <b>fun</b> <a href="primary_fungible_store.md#0x1_primary_fungible_store_primary_store_inlined">primary_store_inlined</a>&lt;T: key&gt;(owner: <b>address</b>, metadata: <a href="object.md#0x1_object_Object">object::Object</a>&lt;T&gt;): <a href="object.md#0x1_object_Object">object::Object</a>&lt;<a href="fungible_asset.md#0x1_fungible_asset_FungibleStore">fungible_asset::FungibleStore</a>&gt;
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b> inline <b>fun</b> <a href="primary_fungible_store.md#0x1_primary_fungible_store_primary_store_inlined">primary_store_inlined</a>&lt;T: key&gt;(owner: <b>address</b>, metadata: Object&lt;T&gt;): Object&lt;FungibleStore&gt; {
<b>let</b> store = <a href="primary_fungible_store.md#0x1_primary_fungible_store_primary_store_address_inlined">primary_store_address_inlined</a>(owner, metadata);
<a href="object.md#0x1_object_address_to_object">object::address_to_object</a>(store)
}
</code></pre>



</details>

<a id="0x1_primary_fungible_store_primary_store_exists_inlined"></a>

## Function `primary_store_exists_inlined`

Return whether the given account's primary store exists.
Use instead of the corresponding view functions for dispatchable hooks to avoid circular dependencies of modules.


<pre><code><b>public</b> <b>fun</b> <a href="primary_fungible_store.md#0x1_primary_fungible_store_primary_store_exists_inlined">primary_store_exists_inlined</a>&lt;T: key&gt;(<a href="account.md#0x1_account">account</a>: <b>address</b>, metadata: <a href="object.md#0x1_object_Object">object::Object</a>&lt;T&gt;): bool
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b> inline <b>fun</b> <a href="primary_fungible_store.md#0x1_primary_fungible_store_primary_store_exists_inlined">primary_store_exists_inlined</a>&lt;T: key&gt;(<a href="account.md#0x1_account">account</a>: <b>address</b>, metadata: Object&lt;T&gt;): bool {
<a href="fungible_asset.md#0x1_fungible_asset_store_exists">fungible_asset::store_exists</a>(<a href="primary_fungible_store.md#0x1_primary_fungible_store_primary_store_address_inlined">primary_store_address_inlined</a>(<a href="account.md#0x1_account">account</a>, metadata))
}
</code></pre>



</details>

<a id="0x1_primary_fungible_store_balance"></a>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,26 @@ module aptos_framework::primary_fungible_store {
fungible_asset::store_exists(primary_store_address(account, metadata))
}

/// Get the address of the primary store for the given account.
/// Use instead of the corresponding view functions for dispatchable hooks to avoid circular dependencies of modules.
public inline fun primary_store_address_inlined<T: key>(owner: address, metadata: Object<T>): address {
let metadata_addr = object::object_address(&metadata);
object::create_user_derived_object_address(owner, metadata_addr)
}

/// Get the primary store object for the given account.
/// Use instead of the corresponding view functions for dispatchable hooks to avoid circular dependencies of modules.
public inline fun primary_store_inlined<T: key>(owner: address, metadata: Object<T>): Object<FungibleStore> {
let store = primary_store_address_inlined(owner, metadata);
object::address_to_object(store)
}

/// Return whether the given account's primary store exists.
/// Use instead of the corresponding view functions for dispatchable hooks to avoid circular dependencies of modules.
public inline fun primary_store_exists_inlined<T: key>(account: address, metadata: Object<T>): bool {
fungible_asset::store_exists(primary_store_address_inlined(account, metadata))
}

#[view]
/// Get the balance of `account`'s primary store.
public fun balance<T: key>(account: address, metadata: Object<T>): u64 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -328,8 +328,10 @@ module stablecoin::usdk {
// Check that the account is not denylisted by checking the frozen flag on the primary store
fun assert_not_denylisted(account: address) {
let metadata = metadata();
if (primary_fungible_store::primary_store_exists(account, metadata)) {
assert!(!fungible_asset::is_frozen(primary_fungible_store::primary_store(account, metadata)), EDENYLISTED);
// CANNOT call into pfs::store_exists in our withdraw/deposit hooks as it creates possibility of a circular dependency.
// Instead, we will call the inlined version of the function.
if (primary_fungible_store::primary_store_exists_inlined(account, metadata)) {
assert!(!fungible_asset::is_frozen(primary_fungible_store::primary_store_inlined(account, metadata)), EDENYLISTED);
}
}

Expand Down

0 comments on commit 5ad91bc

Please sign in to comment.