@gearbox-protocol/sdk 14.12.0-next.40 → 14.12.0-next.42
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.
- package/dist/cjs/preview/preview/buildDelayedPreview.js +38 -16
- package/dist/cjs/sdk/accounts/liquidations/LiquidationsService.js +21 -0
- package/dist/cjs/sdk/accounts/liquidations/MultichainLiquidationsService.js +26 -0
- package/dist/cjs/sdk/accounts/liquidations/helpers.js +29 -2
- package/dist/cjs/sdk/accounts/withdrawal-compressor/intent-codec.js +11 -8
- package/dist/esm/preview/preview/buildDelayedPreview.js +41 -17
- package/dist/esm/sdk/accounts/liquidations/LiquidationsService.js +23 -1
- package/dist/esm/sdk/accounts/liquidations/MultichainLiquidationsService.js +26 -0
- package/dist/esm/sdk/accounts/liquidations/helpers.js +27 -1
- package/dist/esm/sdk/accounts/withdrawal-compressor/intent-codec.js +11 -8
- package/dist/types/preview/preview/buildDelayedPreview.d.ts +8 -26
- package/dist/types/sdk/accounts/liquidations/LiquidationsService.d.ts +5 -1
- package/dist/types/sdk/accounts/liquidations/MultichainLiquidationsService.d.ts +5 -1
- package/dist/types/sdk/accounts/liquidations/helpers.d.ts +12 -0
- package/dist/types/sdk/accounts/liquidations/types.d.ts +55 -0
- package/dist/types/sdk/accounts/withdrawal-compressor/intent-codec.d.ts +1 -1
- package/dist/types/sdk/accounts/withdrawal-compressor/types.d.ts +13 -3
- package/package.json +1 -1
|
@@ -38,23 +38,12 @@ function buildDelayedPreview(afterInstant, before, detected, convert, receivedTo
|
|
|
38
38
|
repayFromClaim(post, request.claimToken, converter.convert, claimed);
|
|
39
39
|
break;
|
|
40
40
|
case "WITHDRAW_COLLATERAL": {
|
|
41
|
-
|
|
42
|
-
intent.withdrawAmount,
|
|
43
|
-
post.balances.getOrZero(intent.withdrawToken)
|
|
44
|
-
);
|
|
45
|
-
if (withdrawn > 0n) {
|
|
46
|
-
post.balances.dec(intent.withdrawToken, withdrawn);
|
|
47
|
-
collateralWithdrawn.upsert(intent.withdrawToken, withdrawn);
|
|
48
|
-
}
|
|
49
|
-
const claimSpentOnWithdrawal = (0, import_viem.isAddressEqual)(
|
|
50
|
-
intent.withdrawToken,
|
|
51
|
-
request.claimToken
|
|
52
|
-
) ? withdrawn : 0n;
|
|
53
|
-
repayFromClaim(
|
|
41
|
+
applyWithdrawCollateral(
|
|
54
42
|
post,
|
|
55
|
-
request
|
|
56
|
-
|
|
57
|
-
|
|
43
|
+
request,
|
|
44
|
+
intent,
|
|
45
|
+
converter,
|
|
46
|
+
collateralWithdrawn
|
|
58
47
|
);
|
|
59
48
|
break;
|
|
60
49
|
}
|
|
@@ -89,6 +78,39 @@ function applyClaim(post, request) {
|
|
|
89
78
|
post.balances.inc(request.claimToken, claimed);
|
|
90
79
|
return claimed;
|
|
91
80
|
}
|
|
81
|
+
function applyWithdrawCollateral(post, request, intent, converter, collateralWithdrawn) {
|
|
82
|
+
const { withdrawToken, withdrawAmount, debtRepaid } = intent;
|
|
83
|
+
const { claimToken } = request;
|
|
84
|
+
const sameToken = (0, import_viem.isAddressEqual)(withdrawToken, claimToken);
|
|
85
|
+
const fromBalance = import_common_utils.BigIntMath.min(
|
|
86
|
+
withdrawAmount,
|
|
87
|
+
post.balances.getOrZero(withdrawToken)
|
|
88
|
+
);
|
|
89
|
+
post.balances.dec(withdrawToken, fromBalance);
|
|
90
|
+
let withdrawn = fromBalance;
|
|
91
|
+
const missing = withdrawAmount - fromBalance;
|
|
92
|
+
if (missing > 0n && !sameToken) {
|
|
93
|
+
const available = post.balances.getOrZero(claimToken);
|
|
94
|
+
const cost = converter.convert(withdrawToken, claimToken, missing);
|
|
95
|
+
if (cost > 0n && cost <= available) {
|
|
96
|
+
post.balances.dec(claimToken, cost);
|
|
97
|
+
withdrawn += missing;
|
|
98
|
+
} else if (available > 0n) {
|
|
99
|
+
post.balances.dec(claimToken, available);
|
|
100
|
+
withdrawn += converter.convert(claimToken, withdrawToken, available);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (withdrawn > 0n) {
|
|
104
|
+
collateralWithdrawn.upsert(withdrawToken, withdrawn);
|
|
105
|
+
}
|
|
106
|
+
const remaining = post.balances.getOrZero(claimToken);
|
|
107
|
+
if (remaining > 0n) {
|
|
108
|
+
const proceeds = converter.convert(claimToken, post.underlying, remaining);
|
|
109
|
+
post.balances.dec(claimToken, remaining);
|
|
110
|
+
post.balances.inc(post.underlying, proceeds);
|
|
111
|
+
post.repay(import_common_utils.BigIntMath.min(proceeds, debtRepaid));
|
|
112
|
+
}
|
|
113
|
+
}
|
|
92
114
|
function repayFromClaim(post, claimToken, convert, amount) {
|
|
93
115
|
const spent = import_common_utils.BigIntMath.min(amount, post.balances.getOrZero(claimToken));
|
|
94
116
|
if (spent <= 0n) {
|
|
@@ -121,6 +121,27 @@ class LiquidationsService extends import_base.SDKConstruct {
|
|
|
121
121
|
}
|
|
122
122
|
return { ...account, receivedAssets };
|
|
123
123
|
}
|
|
124
|
+
/**
|
|
125
|
+
* {@inheritDoc ILiquidationsService.getLiquidatorWithdrawals}
|
|
126
|
+
**/
|
|
127
|
+
async getLiquidatorWithdrawals(props) {
|
|
128
|
+
if (props.networks && !props.networks.includes(this.sdk.networkType)) {
|
|
129
|
+
return [];
|
|
130
|
+
}
|
|
131
|
+
const compressor = this.sdk.withdrawalCompressor;
|
|
132
|
+
if (!compressor) {
|
|
133
|
+
return [];
|
|
134
|
+
}
|
|
135
|
+
await compressor.loadWithdrawableAssets();
|
|
136
|
+
const phantomTokens = new import_utils.AddressSet(
|
|
137
|
+
compressor.getWithdrawableAssets().map((a) => a.withdrawalPhantomToken)
|
|
138
|
+
);
|
|
139
|
+
const current = await compressor.getExternalAccountCurrentWithdrawals(
|
|
140
|
+
props.liquidator,
|
|
141
|
+
...phantomTokens.asArray()
|
|
142
|
+
);
|
|
143
|
+
return (0, import_helpers.toLiquidatorWithdrawals)(current, this.sdk.networkType);
|
|
144
|
+
}
|
|
124
145
|
/**
|
|
125
146
|
* Accounts of expired credit managers with outstanding debt are liquidatable
|
|
126
147
|
* regardless of their health factor.
|
|
@@ -58,6 +58,32 @@ class MultichainLiquidationsService {
|
|
|
58
58
|
async getLiquidationDetails(props) {
|
|
59
59
|
return this.#sdk.chain(props.network).liquidations.getLiquidationDetails(props);
|
|
60
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* {@inheritDoc ILiquidationsService.getLiquidatorWithdrawals}
|
|
63
|
+
**/
|
|
64
|
+
async getLiquidatorWithdrawals(props) {
|
|
65
|
+
const chains = [...this.#sdk.chains.entries()].filter(
|
|
66
|
+
([network]) => !props.networks || props.networks.includes(network)
|
|
67
|
+
);
|
|
68
|
+
const results = await Promise.allSettled(
|
|
69
|
+
chains.map(
|
|
70
|
+
([, chainSdk]) => chainSdk.liquidations.getLiquidatorWithdrawals(props)
|
|
71
|
+
)
|
|
72
|
+
);
|
|
73
|
+
const withdrawals = [];
|
|
74
|
+
results.forEach((result, i) => {
|
|
75
|
+
const [network, chainSdk] = chains[i];
|
|
76
|
+
if (result.status === "fulfilled") {
|
|
77
|
+
withdrawals.push(...result.value);
|
|
78
|
+
} else {
|
|
79
|
+
chainSdk.logger?.warn(
|
|
80
|
+
result.reason,
|
|
81
|
+
`failed to get liquidator withdrawals on ${network}`
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
return withdrawals;
|
|
86
|
+
}
|
|
61
87
|
}
|
|
62
88
|
// Annotate the CommonJS export names for ESM import in node:
|
|
63
89
|
0 && (module.exports = {
|
|
@@ -21,7 +21,8 @@ __export(helpers_exports, {
|
|
|
21
21
|
DUST_THRESHOLD: () => DUST_THRESHOLD,
|
|
22
22
|
calcEstimatedProfit: () => calcEstimatedProfit,
|
|
23
23
|
calcRepaymentAmount: () => calcRepaymentAmount,
|
|
24
|
-
pickMainAsset: () => pickMainAsset
|
|
24
|
+
pickMainAsset: () => pickMainAsset,
|
|
25
|
+
toLiquidatorWithdrawals: () => toLiquidatorWithdrawals
|
|
25
26
|
});
|
|
26
27
|
module.exports = __toCommonJS(helpers_exports);
|
|
27
28
|
var import_constants = require("../../constants/index.js");
|
|
@@ -54,10 +55,36 @@ function pickMainAsset(ca, convert) {
|
|
|
54
55
|
}
|
|
55
56
|
return bestToken;
|
|
56
57
|
}
|
|
58
|
+
function toLiquidatorWithdrawals(current, network) {
|
|
59
|
+
const rows = [];
|
|
60
|
+
for (const w of current.claimable) {
|
|
61
|
+
for (const o of w.outputs) {
|
|
62
|
+
rows.push({
|
|
63
|
+
network,
|
|
64
|
+
sourceToken: w.token,
|
|
65
|
+
token: o.token,
|
|
66
|
+
amount: o.amount
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
for (const w of current.pending) {
|
|
71
|
+
for (const o of w.expectedOutputs) {
|
|
72
|
+
rows.push({
|
|
73
|
+
network,
|
|
74
|
+
sourceToken: w.token,
|
|
75
|
+
token: o.token,
|
|
76
|
+
amount: o.amount,
|
|
77
|
+
claimableAt: w.claimableAt
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return rows;
|
|
82
|
+
}
|
|
57
83
|
// Annotate the CommonJS export names for ESM import in node:
|
|
58
84
|
0 && (module.exports = {
|
|
59
85
|
DUST_THRESHOLD,
|
|
60
86
|
calcEstimatedProfit,
|
|
61
87
|
calcRepaymentAmount,
|
|
62
|
-
pickMainAsset
|
|
88
|
+
pickMainAsset,
|
|
89
|
+
toLiquidatorWithdrawals
|
|
63
90
|
});
|
|
@@ -25,7 +25,7 @@ __export(intent_codec_exports, {
|
|
|
25
25
|
});
|
|
26
26
|
module.exports = __toCommonJS(intent_codec_exports);
|
|
27
27
|
var import_viem = require("viem");
|
|
28
|
-
const DELAYED_INTENT_VERSION =
|
|
28
|
+
const DELAYED_INTENT_VERSION = 2;
|
|
29
29
|
const DELAYED_INTENT_TYPES = {
|
|
30
30
|
INCREASE_LEVERAGE: 1,
|
|
31
31
|
DEPOSIT: 2,
|
|
@@ -43,7 +43,9 @@ const TO_PARAMS = [...HEADER_PARAMS, { type: "address", name: "to" }];
|
|
|
43
43
|
const WITHDRAW_COLLATERAL_PARAMS = [
|
|
44
44
|
...TO_PARAMS,
|
|
45
45
|
{ type: "address", name: "withdrawToken" },
|
|
46
|
-
{ type: "uint256", name: "withdrawAmount" }
|
|
46
|
+
{ type: "uint256", name: "withdrawAmount" },
|
|
47
|
+
{ type: "address", name: "sourceToken" },
|
|
48
|
+
{ type: "uint256", name: "debtRepaid" }
|
|
47
49
|
];
|
|
48
50
|
function encodeDelayedIntent(intent) {
|
|
49
51
|
const version = DELAYED_INTENT_VERSION;
|
|
@@ -58,7 +60,9 @@ function encodeDelayedIntent(intent) {
|
|
|
58
60
|
intentType,
|
|
59
61
|
intent.to,
|
|
60
62
|
intent.withdrawToken,
|
|
61
|
-
intent.withdrawAmount
|
|
63
|
+
intent.withdrawAmount,
|
|
64
|
+
intent.sourceToken,
|
|
65
|
+
intent.debtRepaid
|
|
62
66
|
]);
|
|
63
67
|
case "DEPOSIT":
|
|
64
68
|
case "DEPOSIT_AND_INCREASE_LEVERAGE":
|
|
@@ -86,15 +90,14 @@ function decodeDelayedIntent(data) {
|
|
|
86
90
|
case DELAYED_INTENT_TYPES.DEPOSIT_AND_INCREASE_LEVERAGE:
|
|
87
91
|
return { type: "DEPOSIT_AND_INCREASE_LEVERAGE" };
|
|
88
92
|
case DELAYED_INTENT_TYPES.WITHDRAW_COLLATERAL: {
|
|
89
|
-
const [, , to, withdrawToken, withdrawAmount] = (0, import_viem.decodeAbiParameters)(
|
|
90
|
-
WITHDRAW_COLLATERAL_PARAMS,
|
|
91
|
-
data
|
|
92
|
-
);
|
|
93
|
+
const [, , to, withdrawToken, withdrawAmount, sourceToken, debtRepaid] = (0, import_viem.decodeAbiParameters)(WITHDRAW_COLLATERAL_PARAMS, data);
|
|
93
94
|
return {
|
|
94
95
|
type: "WITHDRAW_COLLATERAL",
|
|
95
96
|
to,
|
|
96
97
|
withdrawToken,
|
|
97
|
-
withdrawAmount
|
|
98
|
+
withdrawAmount,
|
|
99
|
+
sourceToken,
|
|
100
|
+
debtRepaid
|
|
98
101
|
};
|
|
99
102
|
}
|
|
100
103
|
case DELAYED_INTENT_TYPES.CLOSE_ACCOUNT: {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { isAddressEqual } from "viem";
|
|
2
2
|
import { BigIntMath } from "../../common-utils/index.js";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
AssetsMap
|
|
5
|
+
} from "../../sdk/index.js";
|
|
4
6
|
import {
|
|
5
7
|
ERROR_UNPRICEABLE_TOKEN,
|
|
6
8
|
PREVIEW_DUST
|
|
@@ -18,23 +20,12 @@ function buildDelayedPreview(afterInstant, before, detected, convert, receivedTo
|
|
|
18
20
|
repayFromClaim(post, request.claimToken, converter.convert, claimed);
|
|
19
21
|
break;
|
|
20
22
|
case "WITHDRAW_COLLATERAL": {
|
|
21
|
-
|
|
22
|
-
intent.withdrawAmount,
|
|
23
|
-
post.balances.getOrZero(intent.withdrawToken)
|
|
24
|
-
);
|
|
25
|
-
if (withdrawn > 0n) {
|
|
26
|
-
post.balances.dec(intent.withdrawToken, withdrawn);
|
|
27
|
-
collateralWithdrawn.upsert(intent.withdrawToken, withdrawn);
|
|
28
|
-
}
|
|
29
|
-
const claimSpentOnWithdrawal = isAddressEqual(
|
|
30
|
-
intent.withdrawToken,
|
|
31
|
-
request.claimToken
|
|
32
|
-
) ? withdrawn : 0n;
|
|
33
|
-
repayFromClaim(
|
|
23
|
+
applyWithdrawCollateral(
|
|
34
24
|
post,
|
|
35
|
-
request
|
|
36
|
-
|
|
37
|
-
|
|
25
|
+
request,
|
|
26
|
+
intent,
|
|
27
|
+
converter,
|
|
28
|
+
collateralWithdrawn
|
|
38
29
|
);
|
|
39
30
|
break;
|
|
40
31
|
}
|
|
@@ -69,6 +60,39 @@ function applyClaim(post, request) {
|
|
|
69
60
|
post.balances.inc(request.claimToken, claimed);
|
|
70
61
|
return claimed;
|
|
71
62
|
}
|
|
63
|
+
function applyWithdrawCollateral(post, request, intent, converter, collateralWithdrawn) {
|
|
64
|
+
const { withdrawToken, withdrawAmount, debtRepaid } = intent;
|
|
65
|
+
const { claimToken } = request;
|
|
66
|
+
const sameToken = isAddressEqual(withdrawToken, claimToken);
|
|
67
|
+
const fromBalance = BigIntMath.min(
|
|
68
|
+
withdrawAmount,
|
|
69
|
+
post.balances.getOrZero(withdrawToken)
|
|
70
|
+
);
|
|
71
|
+
post.balances.dec(withdrawToken, fromBalance);
|
|
72
|
+
let withdrawn = fromBalance;
|
|
73
|
+
const missing = withdrawAmount - fromBalance;
|
|
74
|
+
if (missing > 0n && !sameToken) {
|
|
75
|
+
const available = post.balances.getOrZero(claimToken);
|
|
76
|
+
const cost = converter.convert(withdrawToken, claimToken, missing);
|
|
77
|
+
if (cost > 0n && cost <= available) {
|
|
78
|
+
post.balances.dec(claimToken, cost);
|
|
79
|
+
withdrawn += missing;
|
|
80
|
+
} else if (available > 0n) {
|
|
81
|
+
post.balances.dec(claimToken, available);
|
|
82
|
+
withdrawn += converter.convert(claimToken, withdrawToken, available);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (withdrawn > 0n) {
|
|
86
|
+
collateralWithdrawn.upsert(withdrawToken, withdrawn);
|
|
87
|
+
}
|
|
88
|
+
const remaining = post.balances.getOrZero(claimToken);
|
|
89
|
+
if (remaining > 0n) {
|
|
90
|
+
const proceeds = converter.convert(claimToken, post.underlying, remaining);
|
|
91
|
+
post.balances.dec(claimToken, remaining);
|
|
92
|
+
post.balances.inc(post.underlying, proceeds);
|
|
93
|
+
post.repay(BigIntMath.min(proceeds, debtRepaid));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
72
96
|
function repayFromClaim(post, claimToken, convert, amount) {
|
|
73
97
|
const spent = BigIntMath.min(amount, post.balances.getOrZero(claimToken));
|
|
74
98
|
if (spent <= 0n) {
|
|
@@ -5,7 +5,8 @@ import {
|
|
|
5
5
|
calcEstimatedProfit,
|
|
6
6
|
calcRepaymentAmount,
|
|
7
7
|
DUST_THRESHOLD,
|
|
8
|
-
pickMainAsset
|
|
8
|
+
pickMainAsset,
|
|
9
|
+
toLiquidatorWithdrawals
|
|
9
10
|
} from "./helpers.js";
|
|
10
11
|
class LiquidationsService extends SDKConstruct {
|
|
11
12
|
/**
|
|
@@ -103,6 +104,27 @@ class LiquidationsService extends SDKConstruct {
|
|
|
103
104
|
}
|
|
104
105
|
return { ...account, receivedAssets };
|
|
105
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* {@inheritDoc ILiquidationsService.getLiquidatorWithdrawals}
|
|
109
|
+
**/
|
|
110
|
+
async getLiquidatorWithdrawals(props) {
|
|
111
|
+
if (props.networks && !props.networks.includes(this.sdk.networkType)) {
|
|
112
|
+
return [];
|
|
113
|
+
}
|
|
114
|
+
const compressor = this.sdk.withdrawalCompressor;
|
|
115
|
+
if (!compressor) {
|
|
116
|
+
return [];
|
|
117
|
+
}
|
|
118
|
+
await compressor.loadWithdrawableAssets();
|
|
119
|
+
const phantomTokens = new AddressSet(
|
|
120
|
+
compressor.getWithdrawableAssets().map((a) => a.withdrawalPhantomToken)
|
|
121
|
+
);
|
|
122
|
+
const current = await compressor.getExternalAccountCurrentWithdrawals(
|
|
123
|
+
props.liquidator,
|
|
124
|
+
...phantomTokens.asArray()
|
|
125
|
+
);
|
|
126
|
+
return toLiquidatorWithdrawals(current, this.sdk.networkType);
|
|
127
|
+
}
|
|
106
128
|
/**
|
|
107
129
|
* Accounts of expired credit managers with outstanding debt are liquidatable
|
|
108
130
|
* regardless of their health factor.
|
|
@@ -35,6 +35,32 @@ class MultichainLiquidationsService {
|
|
|
35
35
|
async getLiquidationDetails(props) {
|
|
36
36
|
return this.#sdk.chain(props.network).liquidations.getLiquidationDetails(props);
|
|
37
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* {@inheritDoc ILiquidationsService.getLiquidatorWithdrawals}
|
|
40
|
+
**/
|
|
41
|
+
async getLiquidatorWithdrawals(props) {
|
|
42
|
+
const chains = [...this.#sdk.chains.entries()].filter(
|
|
43
|
+
([network]) => !props.networks || props.networks.includes(network)
|
|
44
|
+
);
|
|
45
|
+
const results = await Promise.allSettled(
|
|
46
|
+
chains.map(
|
|
47
|
+
([, chainSdk]) => chainSdk.liquidations.getLiquidatorWithdrawals(props)
|
|
48
|
+
)
|
|
49
|
+
);
|
|
50
|
+
const withdrawals = [];
|
|
51
|
+
results.forEach((result, i) => {
|
|
52
|
+
const [network, chainSdk] = chains[i];
|
|
53
|
+
if (result.status === "fulfilled") {
|
|
54
|
+
withdrawals.push(...result.value);
|
|
55
|
+
} else {
|
|
56
|
+
chainSdk.logger?.warn(
|
|
57
|
+
result.reason,
|
|
58
|
+
`failed to get liquidator withdrawals on ${network}`
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
return withdrawals;
|
|
63
|
+
}
|
|
38
64
|
}
|
|
39
65
|
export {
|
|
40
66
|
MultichainLiquidationsService
|
|
@@ -28,9 +28,35 @@ function pickMainAsset(ca, convert) {
|
|
|
28
28
|
}
|
|
29
29
|
return bestToken;
|
|
30
30
|
}
|
|
31
|
+
function toLiquidatorWithdrawals(current, network) {
|
|
32
|
+
const rows = [];
|
|
33
|
+
for (const w of current.claimable) {
|
|
34
|
+
for (const o of w.outputs) {
|
|
35
|
+
rows.push({
|
|
36
|
+
network,
|
|
37
|
+
sourceToken: w.token,
|
|
38
|
+
token: o.token,
|
|
39
|
+
amount: o.amount
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
for (const w of current.pending) {
|
|
44
|
+
for (const o of w.expectedOutputs) {
|
|
45
|
+
rows.push({
|
|
46
|
+
network,
|
|
47
|
+
sourceToken: w.token,
|
|
48
|
+
token: o.token,
|
|
49
|
+
amount: o.amount,
|
|
50
|
+
claimableAt: w.claimableAt
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return rows;
|
|
55
|
+
}
|
|
31
56
|
export {
|
|
32
57
|
DUST_THRESHOLD,
|
|
33
58
|
calcEstimatedProfit,
|
|
34
59
|
calcRepaymentAmount,
|
|
35
|
-
pickMainAsset
|
|
60
|
+
pickMainAsset,
|
|
61
|
+
toLiquidatorWithdrawals
|
|
36
62
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { decodeAbiParameters, encodeAbiParameters } from "viem";
|
|
2
|
-
const DELAYED_INTENT_VERSION =
|
|
2
|
+
const DELAYED_INTENT_VERSION = 2;
|
|
3
3
|
const DELAYED_INTENT_TYPES = {
|
|
4
4
|
INCREASE_LEVERAGE: 1,
|
|
5
5
|
DEPOSIT: 2,
|
|
@@ -17,7 +17,9 @@ const TO_PARAMS = [...HEADER_PARAMS, { type: "address", name: "to" }];
|
|
|
17
17
|
const WITHDRAW_COLLATERAL_PARAMS = [
|
|
18
18
|
...TO_PARAMS,
|
|
19
19
|
{ type: "address", name: "withdrawToken" },
|
|
20
|
-
{ type: "uint256", name: "withdrawAmount" }
|
|
20
|
+
{ type: "uint256", name: "withdrawAmount" },
|
|
21
|
+
{ type: "address", name: "sourceToken" },
|
|
22
|
+
{ type: "uint256", name: "debtRepaid" }
|
|
21
23
|
];
|
|
22
24
|
function encodeDelayedIntent(intent) {
|
|
23
25
|
const version = DELAYED_INTENT_VERSION;
|
|
@@ -32,7 +34,9 @@ function encodeDelayedIntent(intent) {
|
|
|
32
34
|
intentType,
|
|
33
35
|
intent.to,
|
|
34
36
|
intent.withdrawToken,
|
|
35
|
-
intent.withdrawAmount
|
|
37
|
+
intent.withdrawAmount,
|
|
38
|
+
intent.sourceToken,
|
|
39
|
+
intent.debtRepaid
|
|
36
40
|
]);
|
|
37
41
|
case "DEPOSIT":
|
|
38
42
|
case "DEPOSIT_AND_INCREASE_LEVERAGE":
|
|
@@ -60,15 +64,14 @@ function decodeDelayedIntent(data) {
|
|
|
60
64
|
case DELAYED_INTENT_TYPES.DEPOSIT_AND_INCREASE_LEVERAGE:
|
|
61
65
|
return { type: "DEPOSIT_AND_INCREASE_LEVERAGE" };
|
|
62
66
|
case DELAYED_INTENT_TYPES.WITHDRAW_COLLATERAL: {
|
|
63
|
-
const [, , to, withdrawToken, withdrawAmount] = decodeAbiParameters(
|
|
64
|
-
WITHDRAW_COLLATERAL_PARAMS,
|
|
65
|
-
data
|
|
66
|
-
);
|
|
67
|
+
const [, , to, withdrawToken, withdrawAmount, sourceToken, debtRepaid] = decodeAbiParameters(WITHDRAW_COLLATERAL_PARAMS, data);
|
|
67
68
|
return {
|
|
68
69
|
type: "WITHDRAW_COLLATERAL",
|
|
69
70
|
to,
|
|
70
71
|
withdrawToken,
|
|
71
|
-
withdrawAmount
|
|
72
|
+
withdrawAmount,
|
|
73
|
+
sourceToken,
|
|
74
|
+
debtRepaid
|
|
72
75
|
};
|
|
73
76
|
}
|
|
74
77
|
case DELAYED_INTENT_TYPES.CLOSE_ACCOUNT: {
|
|
@@ -8,34 +8,16 @@ import { type InstantOperationPreview } from "./types.js";
|
|
|
8
8
|
export type ConvertFn = (token: Address, to: Address, amount: bigint) => bigint;
|
|
9
9
|
/**
|
|
10
10
|
* Builds the best-effort preview of the account state after the detected
|
|
11
|
-
* delayed withdrawal is claimed and its intent (if any) is resumed
|
|
11
|
+
* delayed withdrawal is claimed and its intent (if any) is resumed:
|
|
12
|
+
* the claim itself followed by the intent-specific tail
|
|
12
13
|
*
|
|
13
|
-
* Pure function:
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* `ERROR_UNPRICEABLE_TOKEN` error on the preview.
|
|
14
|
+
* Pure function: the input states are never mutated and no network access is performed.
|
|
15
|
+
* Swaps are estimated with the injected conversion; tokens it cannot price contribute
|
|
16
|
+
* nothing and set a non-fatal `ERROR_UNPRICEABLE_TOKEN` error on the
|
|
17
|
+
* preview.
|
|
18
18
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* Intent-specific resume:
|
|
23
|
-
* - `CLOSE_ACCOUNT`: everything is swapped into the underlying, the debt is
|
|
24
|
-
* fully repaid and the rest is withdrawn to the user as `receivedToken`
|
|
25
|
-
* (the unwrapped underlying for RWA markets, converting 1:1 with the
|
|
26
|
-
* underlying; the underlying itself otherwise).
|
|
27
|
-
* - `DECREASE_LEVERAGE`: the claimed amount is swapped into the underlying
|
|
28
|
-
* and used to decrease the debt.
|
|
29
|
-
* - `WITHDRAW_COLLATERAL`: the recorded amount of the recorded token is
|
|
30
|
-
* withdrawn to the user, the rest of the claimed amount decreases the debt.
|
|
31
|
-
* - other intents and `intent: undefined`: claim-only, the post-claim swap
|
|
32
|
-
* target is not recoverable from the intent.
|
|
33
|
-
*
|
|
34
|
-
* The changes (`debtChange`, `quotasChange`, `assetsChange`) are reported
|
|
35
|
-
* relative to the account state before the whole transaction, not the
|
|
36
|
-
* post-instant-part state: to the user the delayed preview answers "where will
|
|
37
|
-
* the account end up compared to now", so the transient phantom token
|
|
38
|
-
* (minted by the instant part, burned by the claim) nets out to nothing.
|
|
19
|
+
* The changes (e.g. `debtChange`) are reported relative to the account
|
|
20
|
+
* state before the whole transaction.
|
|
39
21
|
*
|
|
40
22
|
* @param afterInstant - Account state after the instant part of the
|
|
41
23
|
* transaction.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SDKConstruct } from "../../base/index.js";
|
|
2
|
-
import type { GetLiquidatableAccountsProps, GetLiquidationDetailsProps, ILiquidationsService, LiquidatableAccount, LiquidationDetails } from "./types.js";
|
|
2
|
+
import type { GetLiquidatableAccountsProps, GetLiquidationDetailsProps, GetLiquidatorWithdrawalsProps, ILiquidationsService, LiquidatableAccount, LiquidationDetails, LiquidatorWithdrawal } from "./types.js";
|
|
3
3
|
/**
|
|
4
4
|
* Per-chain implementation of {@link ILiquidationsService}.
|
|
5
5
|
*
|
|
@@ -17,4 +17,8 @@ export declare class LiquidationsService extends SDKConstruct implements ILiquid
|
|
|
17
17
|
* {@inheritDoc ILiquidationsService.getLiquidationDetails}
|
|
18
18
|
**/
|
|
19
19
|
getLiquidationDetails(props: GetLiquidationDetailsProps): Promise<LiquidationDetails>;
|
|
20
|
+
/**
|
|
21
|
+
* {@inheritDoc ILiquidationsService.getLiquidatorWithdrawals}
|
|
22
|
+
**/
|
|
23
|
+
getLiquidatorWithdrawals(props: GetLiquidatorWithdrawalsProps): Promise<LiquidatorWithdrawal[]>;
|
|
20
24
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { MultichainSDK } from "../../MultichainSDK.js";
|
|
2
2
|
import type { PluginsMap } from "../../plugins/index.js";
|
|
3
|
-
import type { GetLiquidatableAccountsProps, GetLiquidationDetailsProps, ILiquidationsService, LiquidatableAccount, LiquidationDetails } from "./types.js";
|
|
3
|
+
import type { GetLiquidatableAccountsProps, GetLiquidationDetailsProps, GetLiquidatorWithdrawalsProps, ILiquidationsService, LiquidatableAccount, LiquidationDetails, LiquidatorWithdrawal } from "./types.js";
|
|
4
4
|
/**
|
|
5
5
|
* Cross-chain implementation of {@link ILiquidationsService}.
|
|
6
6
|
*
|
|
@@ -20,4 +20,8 @@ export declare class MultichainLiquidationsService<const Plugins extends Plugins
|
|
|
20
20
|
* {@inheritDoc ILiquidationsService.getLiquidationDetails}
|
|
21
21
|
**/
|
|
22
22
|
getLiquidationDetails(props: GetLiquidationDetailsProps): Promise<LiquidationDetails>;
|
|
23
|
+
/**
|
|
24
|
+
* {@inheritDoc ILiquidationsService.getLiquidatorWithdrawals}
|
|
25
|
+
**/
|
|
26
|
+
getLiquidatorWithdrawals(props: GetLiquidatorWithdrawalsProps): Promise<LiquidatorWithdrawal[]>;
|
|
23
27
|
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type { Address } from "viem";
|
|
2
2
|
import type { CreditAccountData } from "../../base/index.js";
|
|
3
|
+
import type { NetworkType } from "../../chain/index.js";
|
|
4
|
+
import type { CurrentWithdrawals } from "../withdrawal-compressor/index.js";
|
|
5
|
+
import type { LiquidatorWithdrawal } from "./types.js";
|
|
3
6
|
/**
|
|
4
7
|
* Token balances at or below this threshold are treated as dust and ignored,
|
|
5
8
|
* consistent with the rest of the SDK (see `filterDust`).
|
|
@@ -32,3 +35,12 @@ export declare function calcEstimatedProfit(totalValue: bigint, liquidationDisco
|
|
|
32
35
|
* must return `0n` when the price is unavailable
|
|
33
36
|
**/
|
|
34
37
|
export declare function pickMainAsset(ca: CreditAccountData, convert: (token: Address, balance: bigint) => bigint): Address | undefined;
|
|
38
|
+
/**
|
|
39
|
+
* Flattens delayed withdrawals of a liquidator into per-output rows:
|
|
40
|
+
* claimable outputs have no `claimableAt` (claimable now), pending outputs
|
|
41
|
+
* carry the estimated claim timestamp.
|
|
42
|
+
*
|
|
43
|
+
* @param current - Claimable and pending withdrawals from the withdrawal compressor
|
|
44
|
+
* @param network - Network the withdrawals live on
|
|
45
|
+
**/
|
|
46
|
+
export declare function toLiquidatorWithdrawals(current: CurrentWithdrawals, network: NetworkType): LiquidatorWithdrawal[];
|
|
@@ -135,6 +135,53 @@ export interface DelayedReceivedAsset {
|
|
|
135
135
|
* A single asset the liquidator receives when fully liquidating an account.
|
|
136
136
|
**/
|
|
137
137
|
export type ReceivedAsset = InstantReceivedAsset | DelayedReceivedAsset;
|
|
138
|
+
/**
|
|
139
|
+
* Props for {@link ILiquidationsService.getLiquidatorWithdrawals}.
|
|
140
|
+
**/
|
|
141
|
+
export interface GetLiquidatorWithdrawalsProps {
|
|
142
|
+
/**
|
|
143
|
+
* Networks to query. On {@link MultichainLiquidationsService} selects which
|
|
144
|
+
* chains to query; a single-chain service returns an empty list when its
|
|
145
|
+
* own network is excluded.
|
|
146
|
+
**/
|
|
147
|
+
networks?: NetworkType[];
|
|
148
|
+
/**
|
|
149
|
+
* Liquidator wallet that owns the redemption receipts (redeemer contracts
|
|
150
|
+
* received as a result of liquidations).
|
|
151
|
+
**/
|
|
152
|
+
liquidator: Address;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* A single delayed-withdrawal position owned by the liquidator.
|
|
156
|
+
*
|
|
157
|
+
* The redeemer contract address is not included: it is not part of the
|
|
158
|
+
* on-chain withdrawal structs returned by the withdrawal compressor. It can
|
|
159
|
+
* be surfaced later if the compressor structs are extended.
|
|
160
|
+
**/
|
|
161
|
+
export interface LiquidatorWithdrawal {
|
|
162
|
+
/**
|
|
163
|
+
* Network the withdrawal lives on.
|
|
164
|
+
**/
|
|
165
|
+
network: NetworkType;
|
|
166
|
+
/**
|
|
167
|
+
* Source asset spent by the delayed withdrawal (e.g. ACRED).
|
|
168
|
+
**/
|
|
169
|
+
sourceToken: Address;
|
|
170
|
+
/**
|
|
171
|
+
* Receivable asset (e.g. USDC).
|
|
172
|
+
**/
|
|
173
|
+
token: Address;
|
|
174
|
+
/**
|
|
175
|
+
* Amount of `token` receivable: exact for claimable withdrawals, estimated
|
|
176
|
+
* for pending ones.
|
|
177
|
+
**/
|
|
178
|
+
amount: bigint;
|
|
179
|
+
/**
|
|
180
|
+
* Estimated unix timestamp (in seconds) when a pending withdrawal becomes
|
|
181
|
+
* claimable. `undefined` means the withdrawal is claimable now.
|
|
182
|
+
**/
|
|
183
|
+
claimableAt?: bigint;
|
|
184
|
+
}
|
|
138
185
|
/**
|
|
139
186
|
* Detailed information about a liquidatable credit account, extending the
|
|
140
187
|
* list row with the full breakdown of assets the liquidator receives.
|
|
@@ -169,4 +216,12 @@ export interface ILiquidationsService {
|
|
|
169
216
|
* @throws When the account is not found or its collateral computation fails.
|
|
170
217
|
**/
|
|
171
218
|
getLiquidationDetails(props: GetLiquidationDetailsProps): Promise<LiquidationDetails>;
|
|
219
|
+
/**
|
|
220
|
+
* Returns the status of delayed-withdrawal positions (redemption receipts)
|
|
221
|
+
* owned by a liquidator wallet: what is receivable, how much, and when it
|
|
222
|
+
* becomes claimable.
|
|
223
|
+
*
|
|
224
|
+
* @param props - See {@link GetLiquidatorWithdrawalsProps}
|
|
225
|
+
**/
|
|
226
|
+
getLiquidatorWithdrawals(props: GetLiquidatorWithdrawalsProps): Promise<LiquidatorWithdrawal[]>;
|
|
172
227
|
}
|
|
@@ -4,7 +4,7 @@ import type { DelayedIntent } from "./types.js";
|
|
|
4
4
|
* Current version of the delayed intent encoding schema.
|
|
5
5
|
* Bump when the layout of any intent type changes.
|
|
6
6
|
**/
|
|
7
|
-
export declare const DELAYED_INTENT_VERSION =
|
|
7
|
+
export declare const DELAYED_INTENT_VERSION = 2;
|
|
8
8
|
/**
|
|
9
9
|
* Stable uint8 discriminants for intent types.
|
|
10
10
|
* Starts at 1 so that all-zero data cannot decode as a valid intent.
|
|
@@ -31,8 +31,9 @@ export interface DelayedDepositAndIncreaseLeverageIntent {
|
|
|
31
31
|
}
|
|
32
32
|
/**
|
|
33
33
|
* App: 2.1 Withdraw — withdraw selected token at fixed leverage.
|
|
34
|
-
*
|
|
35
|
-
*
|
|
34
|
+
* Primary goal is `withdrawAmount` of `withdrawToken` (W of T). Debt cut is
|
|
35
|
+
* residual from the claim/path after reserving W. `sourceToken` (S) funds the
|
|
36
|
+
* delayed path; `debtRepaid` is 0 when debt was already repaid on start.
|
|
36
37
|
**/
|
|
37
38
|
export interface DelayedWithdrawCollateralIntent {
|
|
38
39
|
type: "WITHDRAW_COLLATERAL";
|
|
@@ -46,9 +47,18 @@ export interface DelayedWithdrawCollateralIntent {
|
|
|
46
47
|
**/
|
|
47
48
|
withdrawToken: Address;
|
|
48
49
|
/**
|
|
49
|
-
* Amount of `withdrawToken` to withdraw to the wallet after the claim
|
|
50
|
+
* Amount of `withdrawToken` to withdraw to the wallet after the claim (W)
|
|
50
51
|
**/
|
|
51
52
|
withdrawAmount: bigint;
|
|
53
|
+
/**
|
|
54
|
+
* Token that funds the delayed path / debt conversion (S)
|
|
55
|
+
**/
|
|
56
|
+
sourceToken: Address;
|
|
57
|
+
/**
|
|
58
|
+
* Desired debt decrease in underlying units remaining for resume.
|
|
59
|
+
* `0n` when debt was already repaid on the delayed-start branch.
|
|
60
|
+
**/
|
|
61
|
+
debtRepaid: bigint;
|
|
52
62
|
}
|
|
53
63
|
/**
|
|
54
64
|
* App: 2.2 Withdraw — close account (receive leftover to wallet).
|