liquid-sdk 1.0.0 → 1.1.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.
- package/README.md +71 -31
- package/dist/index.d.mts +324 -7
- package/dist/index.d.ts +324 -7
- package/dist/index.js +412 -27
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +391 -22
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -21,8 +21,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
ADDRESSES: () => ADDRESSES,
|
|
24
|
+
DEFAULTS: () => DEFAULTS,
|
|
24
25
|
DEFAULT_CHAIN: () => DEFAULT_CHAIN,
|
|
25
26
|
DEFAULT_CHAIN_ID: () => DEFAULT_CHAIN_ID,
|
|
27
|
+
DEFAULT_RPC_URL: () => DEFAULT_RPC_URL,
|
|
28
|
+
DEFAULT_TRANCHES_USD: () => DEFAULT_TRANCHES_USD,
|
|
26
29
|
ERC20Abi: () => ERC20Abi,
|
|
27
30
|
EXTERNAL: () => EXTERNAL,
|
|
28
31
|
FEE: () => FEE,
|
|
@@ -37,12 +40,25 @@ __export(index_exports, {
|
|
|
37
40
|
LiquidSniperAuctionV2Abi: () => LiquidSniperAuctionV2Abi,
|
|
38
41
|
LiquidSniperUtilV2Abi: () => LiquidSniperUtilV2Abi,
|
|
39
42
|
LiquidVaultAbi: () => LiquidVaultAbi,
|
|
40
|
-
|
|
43
|
+
POOL_POSITIONS: () => POOL_POSITIONS,
|
|
44
|
+
TOKEN: () => TOKEN,
|
|
45
|
+
createDefaultPositions: () => createDefaultPositions,
|
|
46
|
+
createPositions: () => createPositions,
|
|
47
|
+
createPositionsUSD: () => createPositionsUSD,
|
|
48
|
+
describePositions: () => describePositions,
|
|
49
|
+
encodeDynamicFeePoolData: () => encodeDynamicFeePoolData,
|
|
50
|
+
encodeSniperAuctionData: () => encodeSniperAuctionData,
|
|
51
|
+
encodeStaticFeePoolData: () => encodeStaticFeePoolData,
|
|
52
|
+
getTickFromMarketCapETH: () => getTickFromMarketCapETH,
|
|
53
|
+
getTickFromMarketCapStable: () => getTickFromMarketCapStable,
|
|
54
|
+
getTickFromMarketCapUSD: () => getTickFromMarketCapUSD,
|
|
55
|
+
marketCapFromTickETH: () => marketCapFromTickETH,
|
|
56
|
+
marketCapFromTickUSD: () => marketCapFromTickUSD
|
|
41
57
|
});
|
|
42
58
|
module.exports = __toCommonJS(index_exports);
|
|
43
59
|
|
|
44
60
|
// src/client.ts
|
|
45
|
-
var
|
|
61
|
+
var import_viem2 = require("viem");
|
|
46
62
|
var import_chains2 = require("viem/chains");
|
|
47
63
|
|
|
48
64
|
// src/constants.ts
|
|
@@ -88,8 +104,154 @@ var TOKEN = {
|
|
|
88
104
|
MAX_EXTENSIONS: 10,
|
|
89
105
|
MAX_EXTENSION_BPS: 9e3
|
|
90
106
|
};
|
|
107
|
+
var POOL_POSITIONS = {
|
|
108
|
+
/** Single position, 100% of liquidity in one range */
|
|
109
|
+
Standard: [
|
|
110
|
+
{
|
|
111
|
+
tickLower: -230400,
|
|
112
|
+
// ~10 ETH / ~$20K
|
|
113
|
+
tickUpper: -12e4,
|
|
114
|
+
// ~$1.5B
|
|
115
|
+
positionBps: 1e4
|
|
116
|
+
}
|
|
117
|
+
],
|
|
118
|
+
/** 3-tranche Liquid default (hardcoded for ~10 ETH start, ~$2070/ETH) */
|
|
119
|
+
Liquid: [
|
|
120
|
+
{
|
|
121
|
+
tickLower: -230400,
|
|
122
|
+
// ~$20K starting
|
|
123
|
+
tickUpper: -198600,
|
|
124
|
+
// ~$500K
|
|
125
|
+
positionBps: 4e3
|
|
126
|
+
// 40%
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
tickLower: -198600,
|
|
130
|
+
// ~$500K
|
|
131
|
+
tickUpper: -168600,
|
|
132
|
+
// ~$10M
|
|
133
|
+
positionBps: 5e3
|
|
134
|
+
// 50%
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
tickLower: -168600,
|
|
138
|
+
// ~$10M
|
|
139
|
+
tickUpper: -122600,
|
|
140
|
+
// ~$1B
|
|
141
|
+
positionBps: 1e3
|
|
142
|
+
// 10%
|
|
143
|
+
}
|
|
144
|
+
]
|
|
145
|
+
};
|
|
146
|
+
var DEFAULTS = {
|
|
147
|
+
HOOK: ADDRESSES.HOOK_STATIC_FEE_V2,
|
|
148
|
+
TICK_SPACING: 200,
|
|
149
|
+
TICK_IF_TOKEN0_IS_LIQUID: -230400,
|
|
150
|
+
/** Static fee on buys (ETH → token): 1% (100 bps). Fees collected in ETH. */
|
|
151
|
+
PAIRED_FEE_BPS: 100,
|
|
152
|
+
/** Static fee on sells (token → ETH): 0%. No fees in liquid token. */
|
|
153
|
+
LIQUID_FEE_BPS: 0,
|
|
154
|
+
/** MEV module: Sniper Auction V2 */
|
|
155
|
+
MEV_MODULE: ADDRESSES.SNIPER_AUCTION_V2,
|
|
156
|
+
/** Sniper auction starting fee: 80% (800,000 uniBps) */
|
|
157
|
+
SNIPER_STARTING_FEE: 8e5,
|
|
158
|
+
/** Sniper auction ending fee: 40% (400,000 uniBps) */
|
|
159
|
+
SNIPER_ENDING_FEE: 4e5,
|
|
160
|
+
/** Sniper auction decay period: 32 seconds */
|
|
161
|
+
SNIPER_SECONDS_TO_DECAY: 32
|
|
162
|
+
};
|
|
91
163
|
var DEFAULT_CHAIN = import_chains.base;
|
|
92
164
|
var DEFAULT_CHAIN_ID = 8453;
|
|
165
|
+
var DEFAULT_RPC_URL = "https://base.drpc.org";
|
|
166
|
+
|
|
167
|
+
// src/utils/encoding.ts
|
|
168
|
+
var import_viem = require("viem");
|
|
169
|
+
var PoolInitializationDataAbi = [
|
|
170
|
+
{
|
|
171
|
+
type: "tuple",
|
|
172
|
+
components: [
|
|
173
|
+
{ name: "extension", type: "address" },
|
|
174
|
+
{ name: "extensionData", type: "bytes" },
|
|
175
|
+
{ name: "feeData", type: "bytes" }
|
|
176
|
+
]
|
|
177
|
+
}
|
|
178
|
+
];
|
|
179
|
+
var StaticFeeInitAbi = [
|
|
180
|
+
{ type: "uint24" },
|
|
181
|
+
{ type: "uint24" }
|
|
182
|
+
];
|
|
183
|
+
var SniperAuctionInitAbi = [
|
|
184
|
+
{
|
|
185
|
+
type: "tuple",
|
|
186
|
+
components: [
|
|
187
|
+
{ name: "startingFee", type: "uint24" },
|
|
188
|
+
{ name: "endingFee", type: "uint24" },
|
|
189
|
+
{ name: "secondsToDecay", type: "uint256" }
|
|
190
|
+
]
|
|
191
|
+
}
|
|
192
|
+
];
|
|
193
|
+
function encodeStaticFeePoolData(liquidFeeBps, pairedFeeBps, extension = import_viem.zeroAddress, extensionData = "0x") {
|
|
194
|
+
const feeData = (0, import_viem.encodeAbiParameters)(StaticFeeInitAbi, [
|
|
195
|
+
liquidFeeBps * 100,
|
|
196
|
+
pairedFeeBps * 100
|
|
197
|
+
]);
|
|
198
|
+
return (0, import_viem.encodeAbiParameters)(PoolInitializationDataAbi, [
|
|
199
|
+
{
|
|
200
|
+
extension,
|
|
201
|
+
extensionData,
|
|
202
|
+
feeData
|
|
203
|
+
}
|
|
204
|
+
]);
|
|
205
|
+
}
|
|
206
|
+
var DynamicFeeInitAbi = [
|
|
207
|
+
{ type: "uint24" },
|
|
208
|
+
// baseFee (uniBps)
|
|
209
|
+
{ type: "uint24" },
|
|
210
|
+
// maxFee (uniBps)
|
|
211
|
+
{ type: "uint256" },
|
|
212
|
+
// referenceTickFilterPeriod
|
|
213
|
+
{ type: "uint256" },
|
|
214
|
+
// resetPeriod
|
|
215
|
+
{ type: "int24" },
|
|
216
|
+
// resetTickFilter
|
|
217
|
+
{ type: "uint256" },
|
|
218
|
+
// feeControlNumerator
|
|
219
|
+
{ type: "uint24" }
|
|
220
|
+
// decayFilterBps
|
|
221
|
+
];
|
|
222
|
+
function encodeDynamicFeePoolData(config, extension = import_viem.zeroAddress, extensionData = "0x") {
|
|
223
|
+
const feeData = (0, import_viem.encodeAbiParameters)(DynamicFeeInitAbi, [
|
|
224
|
+
config.baseFeeBps * 100,
|
|
225
|
+
config.maxFeeBps * 100,
|
|
226
|
+
BigInt(config.referenceTickFilterPeriod),
|
|
227
|
+
BigInt(config.resetPeriod),
|
|
228
|
+
config.resetTickFilter,
|
|
229
|
+
config.feeControlNumerator,
|
|
230
|
+
config.decayFilterBps
|
|
231
|
+
]);
|
|
232
|
+
return (0, import_viem.encodeAbiParameters)(PoolInitializationDataAbi, [
|
|
233
|
+
{
|
|
234
|
+
extension,
|
|
235
|
+
extensionData,
|
|
236
|
+
feeData
|
|
237
|
+
}
|
|
238
|
+
]);
|
|
239
|
+
}
|
|
240
|
+
function encodeSniperAuctionData(config) {
|
|
241
|
+
if (config.startingFee <= config.endingFee) {
|
|
242
|
+
throw new Error("startingFee must be greater than endingFee");
|
|
243
|
+
}
|
|
244
|
+
if (config.secondsToDecay <= 0) {
|
|
245
|
+
throw new Error("secondsToDecay must be positive");
|
|
246
|
+
}
|
|
247
|
+
return (0, import_viem.encodeAbiParameters)(SniperAuctionInitAbi, [
|
|
248
|
+
{
|
|
249
|
+
startingFee: config.startingFee,
|
|
250
|
+
endingFee: config.endingFee,
|
|
251
|
+
secondsToDecay: BigInt(config.secondsToDecay)
|
|
252
|
+
}
|
|
253
|
+
]);
|
|
254
|
+
}
|
|
93
255
|
|
|
94
256
|
// src/abis/LiquidFactory.ts
|
|
95
257
|
var LiquidFactoryAbi = [
|
|
@@ -792,7 +954,7 @@ var LiquidSDK = class {
|
|
|
792
954
|
* The paired token must be WETH for simple dev buys.
|
|
793
955
|
*/
|
|
794
956
|
buildDevBuyExtension(devBuy) {
|
|
795
|
-
const extensionData = (0,
|
|
957
|
+
const extensionData = (0, import_viem2.encodeAbiParameters)(
|
|
796
958
|
[
|
|
797
959
|
{
|
|
798
960
|
type: "tuple",
|
|
@@ -816,11 +978,11 @@ var LiquidSDK = class {
|
|
|
816
978
|
[
|
|
817
979
|
{
|
|
818
980
|
pairedTokenPoolKey: {
|
|
819
|
-
currency0:
|
|
820
|
-
currency1:
|
|
981
|
+
currency0: import_viem2.zeroAddress,
|
|
982
|
+
currency1: import_viem2.zeroAddress,
|
|
821
983
|
fee: 0,
|
|
822
984
|
tickSpacing: 0,
|
|
823
|
-
hooks:
|
|
985
|
+
hooks: import_viem2.zeroAddress
|
|
824
986
|
},
|
|
825
987
|
pairedTokenAmountOutMinimum: 0n,
|
|
826
988
|
recipient: devBuy.recipient
|
|
@@ -834,6 +996,97 @@ var LiquidSDK = class {
|
|
|
834
996
|
extensionData
|
|
835
997
|
};
|
|
836
998
|
}
|
|
999
|
+
// ── Validation ─────────────────────────────────────────────────
|
|
1000
|
+
/**
|
|
1001
|
+
* Validate a DeploymentConfig before sending to the contract.
|
|
1002
|
+
* Catches common mistakes client-side with clear error messages.
|
|
1003
|
+
*/
|
|
1004
|
+
validateDeploymentConfig(config) {
|
|
1005
|
+
const { lockerConfig, extensionConfigs } = config;
|
|
1006
|
+
const { tickSpacing } = config.poolConfig;
|
|
1007
|
+
const posLen = lockerConfig.tickLower.length;
|
|
1008
|
+
if (lockerConfig.tickUpper.length !== posLen || lockerConfig.positionBps.length !== posLen) {
|
|
1009
|
+
throw new Error(
|
|
1010
|
+
`tickLower (${posLen}), tickUpper (${lockerConfig.tickUpper.length}), and positionBps (${lockerConfig.positionBps.length}) arrays must be the same length`
|
|
1011
|
+
);
|
|
1012
|
+
}
|
|
1013
|
+
if (posLen === 0) {
|
|
1014
|
+
throw new Error("At least one position is required");
|
|
1015
|
+
}
|
|
1016
|
+
if (posLen > 7) {
|
|
1017
|
+
throw new Error(`Maximum 7 positions allowed, got ${posLen}`);
|
|
1018
|
+
}
|
|
1019
|
+
const posBpsSum = lockerConfig.positionBps.reduce((s, b) => s + b, 0);
|
|
1020
|
+
if (posBpsSum !== FEE.BPS) {
|
|
1021
|
+
throw new Error(
|
|
1022
|
+
`positionBps must sum to ${FEE.BPS} (100%), got ${posBpsSum}`
|
|
1023
|
+
);
|
|
1024
|
+
}
|
|
1025
|
+
for (let i = 0; i < posLen; i++) {
|
|
1026
|
+
if (lockerConfig.tickLower[i] >= lockerConfig.tickUpper[i]) {
|
|
1027
|
+
throw new Error(
|
|
1028
|
+
`Position ${i}: tickLower (${lockerConfig.tickLower[i]}) must be less than tickUpper (${lockerConfig.tickUpper[i]})`
|
|
1029
|
+
);
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
for (let i = 0; i < posLen; i++) {
|
|
1033
|
+
if (lockerConfig.tickLower[i] % tickSpacing !== 0) {
|
|
1034
|
+
throw new Error(
|
|
1035
|
+
`Position ${i}: tickLower (${lockerConfig.tickLower[i]}) is not a multiple of tickSpacing (${tickSpacing})`
|
|
1036
|
+
);
|
|
1037
|
+
}
|
|
1038
|
+
if (lockerConfig.tickUpper[i] % tickSpacing !== 0) {
|
|
1039
|
+
throw new Error(
|
|
1040
|
+
`Position ${i}: tickUpper (${lockerConfig.tickUpper[i]}) is not a multiple of tickSpacing (${tickSpacing})`
|
|
1041
|
+
);
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
const startingTick = config.poolConfig.tickIfToken0IsLiquid;
|
|
1045
|
+
for (let i = 0; i < posLen; i++) {
|
|
1046
|
+
if (lockerConfig.tickLower[i] < startingTick) {
|
|
1047
|
+
throw new Error(
|
|
1048
|
+
`Position ${i}: tickLower (${lockerConfig.tickLower[i]}) is below the starting tick (${startingTick})`
|
|
1049
|
+
);
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
const touchesStart = lockerConfig.tickLower.some(
|
|
1053
|
+
(t) => t === startingTick
|
|
1054
|
+
);
|
|
1055
|
+
if (!touchesStart) {
|
|
1056
|
+
throw new Error(
|
|
1057
|
+
`At least one position's tickLower must equal tickIfToken0IsLiquid (${startingTick})`
|
|
1058
|
+
);
|
|
1059
|
+
}
|
|
1060
|
+
const rwdLen = lockerConfig.rewardAdmins.length;
|
|
1061
|
+
if (lockerConfig.rewardRecipients.length !== rwdLen || lockerConfig.rewardBps.length !== rwdLen) {
|
|
1062
|
+
throw new Error(
|
|
1063
|
+
`rewardAdmins (${rwdLen}), rewardRecipients (${lockerConfig.rewardRecipients.length}), and rewardBps (${lockerConfig.rewardBps.length}) arrays must be the same length`
|
|
1064
|
+
);
|
|
1065
|
+
}
|
|
1066
|
+
if (rwdLen === 0) {
|
|
1067
|
+
throw new Error("At least one reward recipient is required");
|
|
1068
|
+
}
|
|
1069
|
+
const rwdBpsSum = lockerConfig.rewardBps.reduce((s, b) => s + b, 0);
|
|
1070
|
+
if (rwdBpsSum !== FEE.BPS) {
|
|
1071
|
+
throw new Error(
|
|
1072
|
+
`rewardBps must sum to ${FEE.BPS} (100%), got ${rwdBpsSum}`
|
|
1073
|
+
);
|
|
1074
|
+
}
|
|
1075
|
+
if (extensionConfigs.length > TOKEN.MAX_EXTENSIONS) {
|
|
1076
|
+
throw new Error(
|
|
1077
|
+
`Maximum ${TOKEN.MAX_EXTENSIONS} extensions allowed, got ${extensionConfigs.length}`
|
|
1078
|
+
);
|
|
1079
|
+
}
|
|
1080
|
+
const extBpsSum = extensionConfigs.reduce(
|
|
1081
|
+
(s, e) => s + e.extensionBps,
|
|
1082
|
+
0
|
|
1083
|
+
);
|
|
1084
|
+
if (extBpsSum > TOKEN.MAX_EXTENSION_BPS) {
|
|
1085
|
+
throw new Error(
|
|
1086
|
+
`Total extensionBps (${extBpsSum}) exceeds maximum (${TOKEN.MAX_EXTENSION_BPS})`
|
|
1087
|
+
);
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
837
1090
|
// ── Token Deployment ─────────────────────────────────────────────
|
|
838
1091
|
async deployToken(params) {
|
|
839
1092
|
if (!this.walletClient?.account) {
|
|
@@ -845,8 +1098,8 @@ var LiquidSDK = class {
|
|
|
845
1098
|
tokenAdmin: params.tokenAdmin ?? account,
|
|
846
1099
|
name: params.name,
|
|
847
1100
|
symbol: params.symbol,
|
|
848
|
-
salt: params.salt ?? (0,
|
|
849
|
-
(0,
|
|
1101
|
+
salt: params.salt ?? (0, import_viem2.keccak256)(
|
|
1102
|
+
(0, import_viem2.encodePacked)(
|
|
850
1103
|
["string", "string", "uint256"],
|
|
851
1104
|
[params.name, params.symbol, BigInt(Date.now())]
|
|
852
1105
|
)
|
|
@@ -857,25 +1110,32 @@ var LiquidSDK = class {
|
|
|
857
1110
|
originatingChainId: BigInt(DEFAULT_CHAIN_ID)
|
|
858
1111
|
},
|
|
859
1112
|
poolConfig: {
|
|
860
|
-
hook: params.hook ??
|
|
1113
|
+
hook: params.hook ?? DEFAULTS.HOOK,
|
|
861
1114
|
pairedToken: params.pairedToken ?? EXTERNAL.WETH,
|
|
862
|
-
tickIfToken0IsLiquid: params.tickIfToken0IsLiquid ??
|
|
863
|
-
tickSpacing: params.tickSpacing ??
|
|
864
|
-
poolData: params.poolData ??
|
|
1115
|
+
tickIfToken0IsLiquid: params.tickIfToken0IsLiquid ?? DEFAULTS.TICK_IF_TOKEN0_IS_LIQUID,
|
|
1116
|
+
tickSpacing: params.tickSpacing ?? DEFAULTS.TICK_SPACING,
|
|
1117
|
+
poolData: params.poolData ?? encodeStaticFeePoolData(
|
|
1118
|
+
DEFAULTS.LIQUID_FEE_BPS,
|
|
1119
|
+
DEFAULTS.PAIRED_FEE_BPS
|
|
1120
|
+
)
|
|
865
1121
|
},
|
|
866
1122
|
lockerConfig: {
|
|
867
1123
|
locker: params.locker ?? ADDRESSES.LP_LOCKER,
|
|
868
1124
|
rewardAdmins: params.rewardAdmins ?? [account],
|
|
869
1125
|
rewardRecipients: params.rewardRecipients ?? [account],
|
|
870
1126
|
rewardBps: params.rewardBps ?? [1e4],
|
|
871
|
-
tickLower: params.tickLower ??
|
|
872
|
-
tickUpper: params.tickUpper ??
|
|
873
|
-
positionBps: params.positionBps ??
|
|
1127
|
+
tickLower: params.tickLower ?? POOL_POSITIONS.Liquid.map((p) => p.tickLower),
|
|
1128
|
+
tickUpper: params.tickUpper ?? POOL_POSITIONS.Liquid.map((p) => p.tickUpper),
|
|
1129
|
+
positionBps: params.positionBps ?? POOL_POSITIONS.Liquid.map((p) => p.positionBps),
|
|
874
1130
|
lockerData: params.lockerData ?? "0x"
|
|
875
1131
|
},
|
|
876
1132
|
mevModuleConfig: {
|
|
877
|
-
mevModule: params.mevModule ??
|
|
878
|
-
mevModuleData: params.mevModuleData ??
|
|
1133
|
+
mevModule: params.mevModule ?? DEFAULTS.MEV_MODULE,
|
|
1134
|
+
mevModuleData: params.mevModuleData ?? encodeSniperAuctionData({
|
|
1135
|
+
startingFee: DEFAULTS.SNIPER_STARTING_FEE,
|
|
1136
|
+
endingFee: DEFAULTS.SNIPER_ENDING_FEE,
|
|
1137
|
+
secondsToDecay: DEFAULTS.SNIPER_SECONDS_TO_DECAY
|
|
1138
|
+
})
|
|
879
1139
|
},
|
|
880
1140
|
extensionConfigs: [...params.extensions ?? []]
|
|
881
1141
|
};
|
|
@@ -884,6 +1144,7 @@ var LiquidSDK = class {
|
|
|
884
1144
|
this.buildDevBuyExtension(params.devBuy)
|
|
885
1145
|
);
|
|
886
1146
|
}
|
|
1147
|
+
this.validateDeploymentConfig(deploymentConfig);
|
|
887
1148
|
const msgValue = deploymentConfig.extensionConfigs.reduce(
|
|
888
1149
|
(sum, ext) => sum + ext.msgValue,
|
|
889
1150
|
0n
|
|
@@ -902,7 +1163,7 @@ var LiquidSDK = class {
|
|
|
902
1163
|
});
|
|
903
1164
|
const tokenCreatedLog = receipt.logs.find((log) => {
|
|
904
1165
|
try {
|
|
905
|
-
const decoded2 = (0,
|
|
1166
|
+
const decoded2 = (0, import_viem2.decodeEventLog)({
|
|
906
1167
|
abi: LiquidFactoryAbi,
|
|
907
1168
|
data: log.data,
|
|
908
1169
|
topics: log.topics
|
|
@@ -915,14 +1176,14 @@ var LiquidSDK = class {
|
|
|
915
1176
|
if (!tokenCreatedLog) {
|
|
916
1177
|
throw new Error("TokenCreated event not found in transaction receipt");
|
|
917
1178
|
}
|
|
918
|
-
const decoded = (0,
|
|
1179
|
+
const decoded = (0, import_viem2.decodeEventLog)({
|
|
919
1180
|
abi: LiquidFactoryAbi,
|
|
920
1181
|
data: tokenCreatedLog.data,
|
|
921
1182
|
topics: tokenCreatedLog.topics
|
|
922
1183
|
});
|
|
923
1184
|
const args = decoded.args;
|
|
924
1185
|
return {
|
|
925
|
-
tokenAddress: (0,
|
|
1186
|
+
tokenAddress: (0, import_viem2.getAddress)(args.tokenAddress),
|
|
926
1187
|
txHash,
|
|
927
1188
|
event: {
|
|
928
1189
|
msgSender: args.msgSender,
|
|
@@ -1070,7 +1331,7 @@ var LiquidSDK = class {
|
|
|
1070
1331
|
if (!this.walletClient?.account) {
|
|
1071
1332
|
throw new Error("walletClient with account required for claimFees");
|
|
1072
1333
|
}
|
|
1073
|
-
return this.walletClient.writeContract({
|
|
1334
|
+
return await this.walletClient.writeContract({
|
|
1074
1335
|
address: ADDRESSES.FEE_LOCKER,
|
|
1075
1336
|
abi: LiquidFeeLockerAbi,
|
|
1076
1337
|
functionName: "claim",
|
|
@@ -1109,7 +1370,7 @@ var LiquidSDK = class {
|
|
|
1109
1370
|
if (!this.walletClient?.account) {
|
|
1110
1371
|
throw new Error("walletClient with account required for claimVault");
|
|
1111
1372
|
}
|
|
1112
|
-
return this.walletClient.writeContract({
|
|
1373
|
+
return await this.walletClient.writeContract({
|
|
1113
1374
|
address: ADDRESSES.VAULT,
|
|
1114
1375
|
abi: LiquidVaultAbi,
|
|
1115
1376
|
functionName: "claim",
|
|
@@ -1238,7 +1499,7 @@ var LiquidSDK = class {
|
|
|
1238
1499
|
if (!this.walletClient?.account) {
|
|
1239
1500
|
throw new Error("walletClient with account required for claimAirdrop");
|
|
1240
1501
|
}
|
|
1241
|
-
return this.walletClient.writeContract({
|
|
1502
|
+
return await this.walletClient.writeContract({
|
|
1242
1503
|
address: ADDRESSES.AIRDROP_V2,
|
|
1243
1504
|
abi: LiquidAirdropV2Abi,
|
|
1244
1505
|
functionName: "claim",
|
|
@@ -1272,7 +1533,7 @@ var LiquidSDK = class {
|
|
|
1272
1533
|
throw new Error("walletClient with account required for collectRewards");
|
|
1273
1534
|
}
|
|
1274
1535
|
const locker = lockerAddress ?? ADDRESSES.LP_LOCKER;
|
|
1275
|
-
return this.walletClient.writeContract({
|
|
1536
|
+
return await this.walletClient.writeContract({
|
|
1276
1537
|
address: locker,
|
|
1277
1538
|
abi: LiquidLpLockerAbi,
|
|
1278
1539
|
functionName: "collectRewards",
|
|
@@ -1288,7 +1549,7 @@ var LiquidSDK = class {
|
|
|
1288
1549
|
);
|
|
1289
1550
|
}
|
|
1290
1551
|
const locker = lockerAddress ?? ADDRESSES.LP_LOCKER;
|
|
1291
|
-
return this.walletClient.writeContract({
|
|
1552
|
+
return await this.walletClient.writeContract({
|
|
1292
1553
|
address: locker,
|
|
1293
1554
|
abi: LiquidLpLockerAbi,
|
|
1294
1555
|
functionName: "collectRewardsWithoutUnlock",
|
|
@@ -1304,7 +1565,7 @@ var LiquidSDK = class {
|
|
|
1304
1565
|
);
|
|
1305
1566
|
}
|
|
1306
1567
|
const locker = lockerAddress ?? ADDRESSES.LP_LOCKER;
|
|
1307
|
-
return this.walletClient.writeContract({
|
|
1568
|
+
return await this.walletClient.writeContract({
|
|
1308
1569
|
address: locker,
|
|
1309
1570
|
abi: LiquidLpLockerAbi,
|
|
1310
1571
|
functionName: "updateRewardRecipient",
|
|
@@ -1339,11 +1600,122 @@ var LiquidSDK = class {
|
|
|
1339
1600
|
});
|
|
1340
1601
|
}
|
|
1341
1602
|
};
|
|
1603
|
+
|
|
1604
|
+
// src/utils/tick-math.ts
|
|
1605
|
+
var LOG_BASE = Math.log(1.0001);
|
|
1606
|
+
var DEFAULT_TICK_SPACING = 200;
|
|
1607
|
+
var TOTAL_SUPPLY = 1e11;
|
|
1608
|
+
function getTickFromMarketCapETH(marketCapETH, tickSpacing = DEFAULT_TICK_SPACING) {
|
|
1609
|
+
if (marketCapETH <= 0) throw new Error("marketCapETH must be positive");
|
|
1610
|
+
const price = marketCapETH / TOTAL_SUPPLY;
|
|
1611
|
+
const rawTick = Math.log(price) / LOG_BASE;
|
|
1612
|
+
return Math.floor(rawTick / tickSpacing) * tickSpacing;
|
|
1613
|
+
}
|
|
1614
|
+
function getTickFromMarketCapUSD(marketCapUSD, ethPriceUSD, tickSpacing = DEFAULT_TICK_SPACING) {
|
|
1615
|
+
if (ethPriceUSD <= 0) throw new Error("ethPriceUSD must be positive");
|
|
1616
|
+
return getTickFromMarketCapETH(marketCapUSD / ethPriceUSD, tickSpacing);
|
|
1617
|
+
}
|
|
1618
|
+
function marketCapFromTickETH(tick) {
|
|
1619
|
+
const price = Math.pow(1.0001, tick);
|
|
1620
|
+
return price * TOTAL_SUPPLY;
|
|
1621
|
+
}
|
|
1622
|
+
function marketCapFromTickUSD(tick, ethPriceUSD) {
|
|
1623
|
+
return marketCapFromTickETH(tick) * ethPriceUSD;
|
|
1624
|
+
}
|
|
1625
|
+
function getTickFromMarketCapStable(marketCap, stableDecimals, tickSpacing = DEFAULT_TICK_SPACING) {
|
|
1626
|
+
if (marketCap <= 0) throw new Error("marketCap must be positive");
|
|
1627
|
+
const price = marketCap / Math.pow(10, 29 - stableDecimals);
|
|
1628
|
+
const rawTick = Math.log(price) / LOG_BASE;
|
|
1629
|
+
return Math.floor(rawTick / tickSpacing) * tickSpacing;
|
|
1630
|
+
}
|
|
1631
|
+
|
|
1632
|
+
// src/utils/positions.ts
|
|
1633
|
+
var DEFAULT_TRANCHES_USD = [
|
|
1634
|
+
{ upperMarketCapUSD: 5e5, supplyPct: 40 },
|
|
1635
|
+
{ upperMarketCapUSD: 1e7, supplyPct: 50 },
|
|
1636
|
+
{ upperMarketCapUSD: 1e9, supplyPct: 10 }
|
|
1637
|
+
];
|
|
1638
|
+
function createPositions(startingMarketCapETH, tranches, tickSpacing = 200) {
|
|
1639
|
+
if (tranches.length === 0) throw new Error("At least one tranche is required");
|
|
1640
|
+
if (tranches.length > 7) throw new Error("Maximum 7 positions allowed");
|
|
1641
|
+
const totalPct = tranches.reduce((sum, t) => sum + t.supplyPct, 0);
|
|
1642
|
+
if (Math.abs(totalPct - 100) > 0.01) {
|
|
1643
|
+
throw new Error(`Tranche percentages must sum to 100, got ${totalPct}`);
|
|
1644
|
+
}
|
|
1645
|
+
for (let i = 1; i < tranches.length; i++) {
|
|
1646
|
+
if (tranches[i].upperMarketCapETH <= tranches[i - 1].upperMarketCapETH) {
|
|
1647
|
+
throw new Error("Tranches must be ordered by ascending upperMarketCapETH");
|
|
1648
|
+
}
|
|
1649
|
+
}
|
|
1650
|
+
const startingTick = getTickFromMarketCapETH(startingMarketCapETH, tickSpacing);
|
|
1651
|
+
const tickLower = [];
|
|
1652
|
+
const tickUpper = [];
|
|
1653
|
+
const positionBps = [];
|
|
1654
|
+
let prevTick = startingTick;
|
|
1655
|
+
for (const tranche of tranches) {
|
|
1656
|
+
const upperTick = getTickFromMarketCapETH(tranche.upperMarketCapETH, tickSpacing);
|
|
1657
|
+
if (upperTick <= prevTick) {
|
|
1658
|
+
throw new Error(
|
|
1659
|
+
`Tranche upper market cap ${tranche.upperMarketCapETH} ETH resolves to tick ${upperTick}, which is not above previous tick ${prevTick}. Increase the market cap or reduce tick spacing.`
|
|
1660
|
+
);
|
|
1661
|
+
}
|
|
1662
|
+
tickLower.push(prevTick);
|
|
1663
|
+
tickUpper.push(upperTick);
|
|
1664
|
+
positionBps.push(Math.round(tranche.supplyPct * 100));
|
|
1665
|
+
prevTick = upperTick;
|
|
1666
|
+
}
|
|
1667
|
+
return { tickLower, tickUpper, positionBps };
|
|
1668
|
+
}
|
|
1669
|
+
function createPositionsUSD(startingMarketCapUSD, ethPriceUSD, tranches, tickSpacing = 200) {
|
|
1670
|
+
if (ethPriceUSD <= 0) throw new Error("ethPriceUSD must be positive");
|
|
1671
|
+
const ethTranches = tranches.map((t) => ({
|
|
1672
|
+
upperMarketCapETH: t.upperMarketCapUSD / ethPriceUSD,
|
|
1673
|
+
supplyPct: t.supplyPct
|
|
1674
|
+
}));
|
|
1675
|
+
return createPositions(
|
|
1676
|
+
startingMarketCapUSD / ethPriceUSD,
|
|
1677
|
+
ethTranches,
|
|
1678
|
+
tickSpacing
|
|
1679
|
+
);
|
|
1680
|
+
}
|
|
1681
|
+
function createDefaultPositions(startingMarketCapUSD, ethPriceUSD, tickSpacing = 200) {
|
|
1682
|
+
const positions = createPositionsUSD(
|
|
1683
|
+
startingMarketCapUSD,
|
|
1684
|
+
ethPriceUSD,
|
|
1685
|
+
DEFAULT_TRANCHES_USD,
|
|
1686
|
+
tickSpacing
|
|
1687
|
+
);
|
|
1688
|
+
return {
|
|
1689
|
+
...positions,
|
|
1690
|
+
tickIfToken0IsLiquid: positions.tickLower[0]
|
|
1691
|
+
};
|
|
1692
|
+
}
|
|
1693
|
+
function describePositions(positions, ethPriceUSD) {
|
|
1694
|
+
return positions.tickLower.map((_, i) => {
|
|
1695
|
+
const lowerETH = Math.pow(1.0001, positions.tickLower[i]) * 1e11;
|
|
1696
|
+
const upperETH = Math.pow(1.0001, positions.tickUpper[i]) * 1e11;
|
|
1697
|
+
return {
|
|
1698
|
+
index: i,
|
|
1699
|
+
tickLower: positions.tickLower[i],
|
|
1700
|
+
tickUpper: positions.tickUpper[i],
|
|
1701
|
+
supplyPct: positions.positionBps[i] / 100,
|
|
1702
|
+
marketCapLowerETH: lowerETH,
|
|
1703
|
+
marketCapUpperETH: upperETH,
|
|
1704
|
+
...ethPriceUSD != null && {
|
|
1705
|
+
marketCapLowerUSD: lowerETH * ethPriceUSD,
|
|
1706
|
+
marketCapUpperUSD: upperETH * ethPriceUSD
|
|
1707
|
+
}
|
|
1708
|
+
};
|
|
1709
|
+
});
|
|
1710
|
+
}
|
|
1342
1711
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1343
1712
|
0 && (module.exports = {
|
|
1344
1713
|
ADDRESSES,
|
|
1714
|
+
DEFAULTS,
|
|
1345
1715
|
DEFAULT_CHAIN,
|
|
1346
1716
|
DEFAULT_CHAIN_ID,
|
|
1717
|
+
DEFAULT_RPC_URL,
|
|
1718
|
+
DEFAULT_TRANCHES_USD,
|
|
1347
1719
|
ERC20Abi,
|
|
1348
1720
|
EXTERNAL,
|
|
1349
1721
|
FEE,
|
|
@@ -1358,6 +1730,19 @@ var LiquidSDK = class {
|
|
|
1358
1730
|
LiquidSniperAuctionV2Abi,
|
|
1359
1731
|
LiquidSniperUtilV2Abi,
|
|
1360
1732
|
LiquidVaultAbi,
|
|
1361
|
-
|
|
1733
|
+
POOL_POSITIONS,
|
|
1734
|
+
TOKEN,
|
|
1735
|
+
createDefaultPositions,
|
|
1736
|
+
createPositions,
|
|
1737
|
+
createPositionsUSD,
|
|
1738
|
+
describePositions,
|
|
1739
|
+
encodeDynamicFeePoolData,
|
|
1740
|
+
encodeSniperAuctionData,
|
|
1741
|
+
encodeStaticFeePoolData,
|
|
1742
|
+
getTickFromMarketCapETH,
|
|
1743
|
+
getTickFromMarketCapStable,
|
|
1744
|
+
getTickFromMarketCapUSD,
|
|
1745
|
+
marketCapFromTickETH,
|
|
1746
|
+
marketCapFromTickUSD
|
|
1362
1747
|
});
|
|
1363
1748
|
//# sourceMappingURL=index.js.map
|