@ember-finance/sdk 2.33.0 → 2.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -62,6 +62,12 @@ export declare class SuiAtomicLiquidityReader {
|
|
|
62
62
|
private readTableValue;
|
|
63
63
|
/** Rate value (1e9) of any vault object (ALV or source EmberVault). */
|
|
64
64
|
private rateValue;
|
|
65
|
+
/**
|
|
66
|
+
* Platform fee a collection would settle at `atMs` (epoch ms), in collateral base units.
|
|
67
|
+
* @param vaultId The id of the atomic vault
|
|
68
|
+
* @param atMs Time to project the fee to
|
|
69
|
+
*/
|
|
70
|
+
getPlatformFeeDue(vaultId: string, atMs: bigint): Promise<bigint>;
|
|
65
71
|
/** Per-source-share EmberShare config from the `ember_share_configs` table. */
|
|
66
72
|
getEmberShareConfig(vaultId: string, sourceVaultId: string): Promise<{
|
|
67
73
|
whitelisted: boolean;
|
|
@@ -131,6 +131,27 @@ export class SuiAtomicLiquidityReader {
|
|
|
131
131
|
const fields = unwrapMoveFields(res.object?.json);
|
|
132
132
|
return toBig(unwrapMoveFields(fields?.rate)?.value);
|
|
133
133
|
}
|
|
134
|
+
/**
|
|
135
|
+
* Platform fee a collection would settle at `atMs` (epoch ms), in collateral base units.
|
|
136
|
+
* @param vaultId The id of the atomic vault
|
|
137
|
+
* @param atMs Time to project the fee to
|
|
138
|
+
*/
|
|
139
|
+
async getPlatformFeeDue(vaultId, atMs) {
|
|
140
|
+
// collect_platform_fee charges the time since last_charged_at before settling:
|
|
141
|
+
// accrued + tvl' * fee_percentage * elapsed_ms / 31_536_000e12, where tvl' is
|
|
142
|
+
// TVL (div(total_shares, rate)) net of the already-accrued fee.
|
|
143
|
+
const fields = await this.vaultFields(vaultId);
|
|
144
|
+
const fee = unwrapMoveFields(fields.fee) ?? {};
|
|
145
|
+
const accrued = toBig(fee.accrued);
|
|
146
|
+
const lastChargedAt = toBig(fee.last_charged_at);
|
|
147
|
+
const feePercentage = toBig(fields.fee_percentage);
|
|
148
|
+
if (atMs <= lastChargedAt || feePercentage === 0n)
|
|
149
|
+
return accrued;
|
|
150
|
+
const tvl = divFloor(toBig(fields.total_shares), toBig(unwrapMoveFields(fields.rate)?.value));
|
|
151
|
+
const base = tvl > accrued ? tvl - accrued : 0n;
|
|
152
|
+
return (accrued +
|
|
153
|
+
(base * feePercentage * (atMs - lastChargedAt)) / 31536000000000000000n);
|
|
154
|
+
}
|
|
134
155
|
/** Per-source-share EmberShare config from the `ember_share_configs` table. */
|
|
135
156
|
async getEmberShareConfig(vaultId, sourceVaultId) {
|
|
136
157
|
const fields = await this.vaultFields(vaultId);
|
|
@@ -139,7 +139,8 @@ export declare class OperatorCalls extends OnChainCalls {
|
|
|
139
139
|
*/
|
|
140
140
|
atomicProcessWithdrawalRequestsUpToTimestamp(vaultId: string, timestamp: NumStr, options?: IVaultOptionalParams & SuiTransactionBlockResponseOptions): Promise<OnChainCallResponse>;
|
|
141
141
|
/**
|
|
142
|
-
* Collect the platform fee of an atomic vault
|
|
142
|
+
* Collect the platform fee of an atomic vault. On a strategy vault, pulls any
|
|
143
|
+
* shortfall from the strategy first, in the same transaction.
|
|
143
144
|
* @param vaultId The id of the atomic vault
|
|
144
145
|
* @param loss The reported loss amount
|
|
145
146
|
* @param options Optional tx execution params
|
|
@@ -252,7 +252,8 @@ export class OperatorCalls extends OnChainCalls {
|
|
|
252
252
|
return this.execCall(txb, options);
|
|
253
253
|
}
|
|
254
254
|
/**
|
|
255
|
-
* Collect the platform fee of an atomic vault
|
|
255
|
+
* Collect the platform fee of an atomic vault. On a strategy vault, pulls any
|
|
256
|
+
* shortfall from the strategy first, in the same transaction.
|
|
256
257
|
* @param vaultId The id of the atomic vault
|
|
257
258
|
* @param loss The reported loss amount
|
|
258
259
|
* @param options Optional tx execution params
|
|
@@ -260,6 +261,24 @@ export class OperatorCalls extends OnChainCalls {
|
|
|
260
261
|
*/
|
|
261
262
|
async atomicCollectPlatformFee(vaultId, loss, options) {
|
|
262
263
|
const txb = options?.txBlock || new TransactionBlock();
|
|
264
|
+
// Unlike EVM's collectPlatformFee, the Sui collection pays from idle balance only
|
|
265
|
+
// and aborts when it is short, so the strategy is drawn on first. The fee keeps
|
|
266
|
+
// accruing until the tx lands, so it is projected a few minutes ahead; whatever
|
|
267
|
+
// is pulled beyond the payout stays idle in the vault.
|
|
268
|
+
const reader = new SuiAtomicLiquidityReader(this.suiClient);
|
|
269
|
+
const target = await reader.getStrategyTarget(vaultId);
|
|
270
|
+
if (target.strategy === "suilend") {
|
|
271
|
+
const landsBy = BigInt(Date.now() + 10 * 60 * 1000);
|
|
272
|
+
const due = await reader.getPlatformFeeDue(vaultId, landsBy);
|
|
273
|
+
const payout = due > BigInt(loss) ? due - BigInt(loss) : 0n;
|
|
274
|
+
const shortfall = payout - target.idleCollateral;
|
|
275
|
+
if (shortfall > 0n) {
|
|
276
|
+
const withdraw = isSuiCoinType(target.collateralType)
|
|
277
|
+
? this.txBuilder.atomicWithdrawFromSuilendStrategySui.bind(this.txBuilder)
|
|
278
|
+
: this.txBuilder.atomicWithdrawFromSuilendStrategy.bind(this.txBuilder);
|
|
279
|
+
withdraw(vaultId, target.suilendPoolType, target.suilendMarketId, shortfall.toString(), { ...options, txBlock: txb });
|
|
280
|
+
}
|
|
281
|
+
}
|
|
263
282
|
this.txBuilder.atomicCollectPlatformFee(vaultId, loss, {
|
|
264
283
|
...options,
|
|
265
284
|
txBlock: txb
|