Skip to content

Commit f4f5932

Browse files
committed
Split DeepBook core account data module
1 parent d8291a9 commit f4f5932

3 files changed

Lines changed: 310 additions & 217 deletions

File tree

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
// Copyright (c) Mysten Labs, Inc.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
/// Account app-data for the DeepBook core wrapper. This module owns the embedded
5+
/// balance manager slot and exposes only package-scoped helpers for the public
6+
/// facade to fund, trade, and sweep through that manager.
7+
module deepbook_core_account::account_data;
8+
9+
use account::{
10+
account::{Account, Auth},
11+
account_registry::{Self as account_registry, AccountRegistry}
12+
};
13+
use deepbook::{
14+
balance_manager::{Self, BalanceManager, DepositCap, TradeCap, TradeProof, WithdrawCap},
15+
registry::Registry
16+
};
17+
use std::internal::permit;
18+
use sui::coin::{Self, Coin};
19+
use token::deep::DEEP;
20+
21+
/// App witness that namespaces DeepBook core account data on an `Account`.
22+
public struct DeepbookCoreAccountApp has drop {}
23+
24+
/// Per-account DeepBook core state. The embedded manager ID is stable across all
25+
/// wrapped calls, so resting orders remain addressable by DeepBook core state.
26+
public struct DeepbookCoreAccountData has store {
27+
balance_manager: BalanceManager,
28+
deposit_cap: DepositCap,
29+
withdraw_cap: WithdrawCap,
30+
trade_cap: TradeCap,
31+
}
32+
33+
/// Return whether this account already has a DeepBook core account slot.
34+
public fun is_initialized(account: &Account): bool {
35+
account.has_data<DeepbookCoreAccountApp>()
36+
}
37+
38+
/// Return this account's embedded balance-manager ID, if the slot exists.
39+
public fun balance_manager_id(account: &Account): Option<ID> {
40+
if (!is_initialized(account)) {
41+
option::none()
42+
} else {
43+
option::some(borrow(account).balance_manager.id())
44+
}
45+
}
46+
47+
/// Return the free balance of `T` currently sitting in the embedded manager.
48+
public fun balance_manager_balance<T>(account: &Account): u64 {
49+
if (!is_initialized(account)) {
50+
0
51+
} else {
52+
borrow(account).balance_manager.balance<T>()
53+
}
54+
}
55+
56+
public(package) fun generate_auth_as_app(account_registry: &AccountRegistry): Auth {
57+
account_registry::generate_auth_as_app<DeepbookCoreAccountApp>(
58+
account_registry,
59+
permit<DeepbookCoreAccountApp>(),
60+
)
61+
}
62+
63+
public(package) fun borrow(account: &Account): &DeepbookCoreAccountData {
64+
account.borrow_data<DeepbookCoreAccountApp, DeepbookCoreAccountData>()
65+
}
66+
67+
public(package) fun ensure(
68+
account: &mut Account,
69+
deepbook_registry: &Registry,
70+
ctx: &mut TxContext,
71+
) {
72+
if (!is_initialized(account)) {
73+
let (
74+
balance_manager,
75+
deposit_cap,
76+
withdraw_cap,
77+
trade_cap,
78+
) = balance_manager::new_with_custom_owner_caps_v2<DeepbookCoreAccountApp>(
79+
DeepbookCoreAccountApp {},
80+
deepbook_registry,
81+
account.account_id().to_address(),
82+
ctx,
83+
);
84+
account.attach(
85+
permit<DeepbookCoreAccountApp>(),
86+
DeepbookCoreAccountData { balance_manager, deposit_cap, withdraw_cap, trade_cap },
87+
);
88+
};
89+
}
90+
91+
public(package) fun borrow_mut(account: &mut Account): &mut DeepbookCoreAccountData {
92+
account.borrow_data_mut<DeepbookCoreAccountApp, DeepbookCoreAccountData>(
93+
permit<DeepbookCoreAccountApp>(),
94+
)
95+
}
96+
97+
public(package) fun balance_manager(d: &DeepbookCoreAccountData): &BalanceManager {
98+
&d.balance_manager
99+
}
100+
101+
public(package) fun balance_manager_mut(d: &mut DeepbookCoreAccountData): &mut BalanceManager {
102+
&mut d.balance_manager
103+
}
104+
105+
public(package) fun generate_trader_proof(
106+
d: &mut DeepbookCoreAccountData,
107+
ctx: &TxContext,
108+
): TradeProof {
109+
d.balance_manager.generate_proof_as_trader(&d.trade_cap, ctx)
110+
}
111+
112+
public(package) fun sweep_all<BaseAsset, QuoteAsset>(
113+
d: &mut DeepbookCoreAccountData,
114+
ctx: &mut TxContext,
115+
): (Coin<BaseAsset>, Coin<QuoteAsset>, Coin<DEEP>) {
116+
(
117+
sweep_from_manager<BaseAsset>(d, ctx),
118+
sweep_from_manager<QuoteAsset>(d, ctx),
119+
sweep_from_manager<DEEP>(d, ctx),
120+
)
121+
}
122+
123+
public(package) fun deposit_all<BaseAsset, QuoteAsset>(
124+
account: &mut Account,
125+
base: Coin<BaseAsset>,
126+
quote: Coin<QuoteAsset>,
127+
deep: Coin<DEEP>,
128+
) {
129+
deposit_to_account_if_nonzero<BaseAsset>(account, base);
130+
deposit_to_account_if_nonzero<QuoteAsset>(account, quote);
131+
deposit_to_account_if_nonzero<DEEP>(account, deep);
132+
}
133+
134+
public(package) fun withdraw_or_zero<T>(
135+
account: &mut Account,
136+
amount: u64,
137+
ctx: &mut TxContext,
138+
): Coin<T> {
139+
if (amount == 0) {
140+
coin::zero<T>(ctx)
141+
} else {
142+
account.withdraw<T>(amount, ctx)
143+
}
144+
}
145+
146+
public(package) fun deposit_to_manager_if_nonzero<T>(
147+
d: &mut DeepbookCoreAccountData,
148+
coin: Coin<T>,
149+
ctx: &TxContext,
150+
) {
151+
if (coin.value() == 0) {
152+
coin.destroy_zero();
153+
} else {
154+
d.balance_manager.deposit_with_cap<T>(&d.deposit_cap, coin, ctx);
155+
}
156+
}
157+
158+
fun sweep_from_manager<T>(d: &mut DeepbookCoreAccountData, ctx: &mut TxContext): Coin<T> {
159+
let amount = d.balance_manager.balance<T>();
160+
if (amount == 0) {
161+
coin::zero<T>(ctx)
162+
} else {
163+
d.balance_manager.withdraw_with_cap<T>(&d.withdraw_cap, amount, ctx)
164+
}
165+
}
166+
167+
fun deposit_to_account_if_nonzero<T>(account: &mut Account, coin: Coin<T>) {
168+
if (coin.value() == 0) {
169+
coin.destroy_zero();
170+
} else {
171+
account.deposit<T>(coin);
172+
}
173+
}

0 commit comments

Comments
 (0)