@floorlaunchpad/sdk-evm 0.0.0-stage → 0.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/LICENSE +61 -0
- package/README.md +154 -2
- package/dist/abi/floor.d.ts +1315 -0
- package/dist/abi/floor.d.ts.map +1 -0
- package/dist/abi/floor.js +154 -0
- package/dist/abi/floor.js.map +1 -0
- package/dist/abi/generated.d.ts +12824 -0
- package/dist/abi/generated.d.ts.map +1 -0
- package/dist/abi/generated.js +1264 -0
- package/dist/abi/generated.js.map +1 -0
- package/dist/abi/index.d.ts +2 -0
- package/dist/abi/index.d.ts.map +1 -0
- package/dist/abi/index.js +2 -0
- package/dist/abi/index.js.map +1 -0
- package/dist/adapter.d.ts +89 -0
- package/dist/adapter.d.ts.map +1 -0
- package/dist/adapter.js +250 -0
- package/dist/adapter.js.map +1 -0
- package/dist/deployments.d.ts +154 -0
- package/dist/deployments.d.ts.map +1 -0
- package/dist/deployments.js +368 -0
- package/dist/deployments.js.map +1 -0
- package/dist/errors.d.ts +56 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +42 -0
- package/dist/errors.js.map +1 -0
- package/dist/events.d.ts +45 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +78 -0
- package/dist/events.js.map +1 -0
- package/dist/fees.d.ts +100 -0
- package/dist/fees.d.ts.map +1 -0
- package/dist/fees.js +156 -0
- package/dist/fees.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/pool.d.ts +63 -0
- package/dist/pool.d.ts.map +1 -0
- package/dist/pool.js +118 -0
- package/dist/pool.js.map +1 -0
- package/dist/reads.d.ts +107 -0
- package/dist/reads.d.ts.map +1 -0
- package/dist/reads.js +201 -0
- package/dist/reads.js.map +1 -0
- package/dist/router.d.ts +99 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +132 -0
- package/dist/router.js.map +1 -0
- package/dist/sale.d.ts +79 -0
- package/dist/sale.d.ts.map +1 -0
- package/dist/sale.js +123 -0
- package/dist/sale.js.map +1 -0
- package/dist/send.d.ts +64 -0
- package/dist/send.d.ts.map +1 -0
- package/dist/send.js +137 -0
- package/dist/send.js.map +1 -0
- package/dist/simulate.d.ts +180 -0
- package/dist/simulate.d.ts.map +1 -0
- package/dist/simulate.js +270 -0
- package/dist/simulate.js.map +1 -0
- package/dist/trade.d.ts +140 -0
- package/dist/trade.d.ts.map +1 -0
- package/dist/trade.js +170 -0
- package/dist/trade.js.map +1 -0
- package/package.json +43 -4
package/dist/simulate.js
ADDED
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import { floorDeploymentFor, rulesOf } from './deployments.js';
|
|
2
|
+
import { FloorEvmError } from './errors.js';
|
|
3
|
+
import { gapSkimBps, hookTakes, skimBpsAt } from './fees.js';
|
|
4
|
+
import { bandTicks, LP_FEE_PIPS, marketTick, MAX_SQRT, MAX_TICK, MIN_SQRT, MIN_TICK, sqrtPriceAtTick } from './pool.js';
|
|
5
|
+
import { poolRatesOf, readCushion, readPoolState } from './reads.js';
|
|
6
|
+
// ---------------------------------------------------------------- v4-core math (FullMath, SqrtPriceMath, SwapMath, TickMath)
|
|
7
|
+
const Q96 = 1n << 96n;
|
|
8
|
+
const MAX_U256 = (1n << 256n) - 1n;
|
|
9
|
+
const MAX_SWAP_FEE = 1000000n;
|
|
10
|
+
const mulDiv = (a, b, d) => (a * b) / d;
|
|
11
|
+
const mulDivRoundingUp = (a, b, d) => {
|
|
12
|
+
const p = a * b;
|
|
13
|
+
return p / d + (p % d === 0n ? 0n : 1n);
|
|
14
|
+
};
|
|
15
|
+
const divRoundingUp = (a, b) => a / b + (a % b === 0n ? 0n : 1n);
|
|
16
|
+
/** `SqrtPriceMath.getAmount0Delta(a, b, liquidity, roundUp)`. */
|
|
17
|
+
export function getAmount0Delta(a, b, liquidity, roundUp) {
|
|
18
|
+
if (a > b)
|
|
19
|
+
[a, b] = [b, a];
|
|
20
|
+
if (a === 0n)
|
|
21
|
+
throw new RangeError('getAmount0Delta: zero price');
|
|
22
|
+
const n1 = liquidity << 96n;
|
|
23
|
+
const n2 = b - a;
|
|
24
|
+
return roundUp ? divRoundingUp(mulDivRoundingUp(n1, n2, b), a) : mulDiv(n1, n2, b) / a;
|
|
25
|
+
}
|
|
26
|
+
/** `SqrtPriceMath.getAmount1Delta(a, b, liquidity, roundUp)`. */
|
|
27
|
+
export function getAmount1Delta(a, b, liquidity, roundUp) {
|
|
28
|
+
const diff = a > b ? a - b : b - a;
|
|
29
|
+
const p = liquidity * diff;
|
|
30
|
+
return p / Q96 + (roundUp && p % Q96 !== 0n ? 1n : 0n);
|
|
31
|
+
}
|
|
32
|
+
function nextSqrtFromAmount0RoundingUp(sqrtP, liquidity, amount) {
|
|
33
|
+
if (amount === 0n)
|
|
34
|
+
return sqrtP;
|
|
35
|
+
const n1 = liquidity << 96n;
|
|
36
|
+
const product = amount * sqrtP;
|
|
37
|
+
if (product <= MAX_U256) {
|
|
38
|
+
const denominator = n1 + product;
|
|
39
|
+
if (denominator <= MAX_U256)
|
|
40
|
+
return mulDivRoundingUp(n1, sqrtP, denominator);
|
|
41
|
+
}
|
|
42
|
+
return divRoundingUp(n1, n1 / sqrtP + amount);
|
|
43
|
+
}
|
|
44
|
+
function nextSqrtFromAmount1RoundingDown(sqrtP, liquidity, amount) {
|
|
45
|
+
const quotient = amount <= (1n << 160n) - 1n ? (amount << 96n) / liquidity : mulDiv(amount, Q96, liquidity);
|
|
46
|
+
const next = sqrtP + quotient;
|
|
47
|
+
if (next >= 1n << 160n)
|
|
48
|
+
throw new RangeError('getNextSqrtPriceFromAmount1RoundingDown: overflow');
|
|
49
|
+
return next;
|
|
50
|
+
}
|
|
51
|
+
/** `SqrtPriceMath.getNextSqrtPriceFromInput`. */
|
|
52
|
+
export function getNextSqrtPriceFromInput(sqrtP, liquidity, amountIn, zeroForOne) {
|
|
53
|
+
if (sqrtP === 0n || liquidity === 0n)
|
|
54
|
+
throw new RangeError('getNextSqrtPriceFromInput: zero price or liquidity');
|
|
55
|
+
return zeroForOne ? nextSqrtFromAmount0RoundingUp(sqrtP, liquidity, amountIn) : nextSqrtFromAmount1RoundingDown(sqrtP, liquidity, amountIn);
|
|
56
|
+
}
|
|
57
|
+
/** `SwapMath.computeSwapStep`, exact input only (an exact-output swap never reaches a FLOOR pool). */
|
|
58
|
+
export function computeSwapStepExactIn(sqrtCurrent, sqrtTarget, liquidity, amountRemaining, feePips) {
|
|
59
|
+
const zeroForOne = sqrtCurrent >= sqrtTarget;
|
|
60
|
+
const lessFee = mulDiv(amountRemaining, MAX_SWAP_FEE - feePips, MAX_SWAP_FEE);
|
|
61
|
+
let amountIn = zeroForOne ? getAmount0Delta(sqrtTarget, sqrtCurrent, liquidity, true) : getAmount1Delta(sqrtCurrent, sqrtTarget, liquidity, true);
|
|
62
|
+
let sqrtNext;
|
|
63
|
+
let feeAmount;
|
|
64
|
+
if (lessFee >= amountIn) {
|
|
65
|
+
sqrtNext = sqrtTarget;
|
|
66
|
+
feeAmount = feePips === MAX_SWAP_FEE ? amountIn : mulDivRoundingUp(amountIn, feePips, MAX_SWAP_FEE - feePips);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
amountIn = lessFee;
|
|
70
|
+
sqrtNext = getNextSqrtPriceFromInput(sqrtCurrent, liquidity, lessFee, zeroForOne);
|
|
71
|
+
feeAmount = amountRemaining - amountIn;
|
|
72
|
+
}
|
|
73
|
+
const amountOut = zeroForOne ? getAmount1Delta(sqrtNext, sqrtCurrent, liquidity, false) : getAmount0Delta(sqrtCurrent, sqrtNext, liquidity, false);
|
|
74
|
+
return { sqrtNext, amountIn, amountOut, feeAmount };
|
|
75
|
+
}
|
|
76
|
+
const msb = (x) => x.toString(2).length - 1;
|
|
77
|
+
const lsb = (x) => msb(x & -x);
|
|
78
|
+
/** `TickMath.getTickAtSqrtPrice`, exactly. */
|
|
79
|
+
export function getTickAtSqrtPrice(sqrtPriceX96) {
|
|
80
|
+
if (sqrtPriceX96 < MIN_SQRT || sqrtPriceX96 >= MAX_SQRT)
|
|
81
|
+
throw new RangeError(`getTickAtSqrtPrice: ${sqrtPriceX96} out of range`);
|
|
82
|
+
const price = sqrtPriceX96 << 32n;
|
|
83
|
+
const m = msb(price);
|
|
84
|
+
let r = m >= 128 ? price >> BigInt(m - 127) : price << BigInt(127 - m);
|
|
85
|
+
let log2 = BigInt(m - 128) << 64n;
|
|
86
|
+
for (let shift = 63n; shift >= 50n; shift--) {
|
|
87
|
+
r = (r * r) >> 127n;
|
|
88
|
+
const f = r >> 128n;
|
|
89
|
+
log2 |= f << shift;
|
|
90
|
+
r >>= f;
|
|
91
|
+
}
|
|
92
|
+
const logSqrt10001 = log2 * 255738958999603826347141n;
|
|
93
|
+
const tickLow = Number((logSqrt10001 - 3402992956809132418596140100660247210n) >> 128n);
|
|
94
|
+
const tickHi = Number((logSqrt10001 + 291339464771989622907027621153398088495n) >> 128n);
|
|
95
|
+
return tickLow === tickHi ? tickLow : sqrtPriceAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow;
|
|
96
|
+
}
|
|
97
|
+
const compress = (tick, spacing) => Math.floor(tick / spacing);
|
|
98
|
+
/** `TickBitmap.nextInitializedTickWithinOneWord`. */
|
|
99
|
+
function nextInitializedTickWithinOneWord(bitmap, tick, spacing, lte) {
|
|
100
|
+
let compressed = compress(tick, spacing);
|
|
101
|
+
if (lte) {
|
|
102
|
+
const wordPos = compressed >> 8;
|
|
103
|
+
const bitPos = compressed & 0xff;
|
|
104
|
+
const mask = MAX_U256 >> BigInt(255 - bitPos);
|
|
105
|
+
const masked = (bitmap.get(wordPos) ?? 0n) & mask;
|
|
106
|
+
const initialized = masked !== 0n;
|
|
107
|
+
const next = initialized ? (compressed - (bitPos - msb(masked))) * spacing : (compressed - bitPos) * spacing;
|
|
108
|
+
return { next, initialized };
|
|
109
|
+
}
|
|
110
|
+
compressed += 1;
|
|
111
|
+
const wordPos = compressed >> 8;
|
|
112
|
+
const bitPos = compressed & 0xff;
|
|
113
|
+
const mask = MAX_U256 ^ ((1n << BigInt(bitPos)) - 1n);
|
|
114
|
+
const masked = (bitmap.get(wordPos) ?? 0n) & mask;
|
|
115
|
+
const initialized = masked !== 0n;
|
|
116
|
+
const next = initialized ? (compressed + (lsb(masked) - bitPos)) * spacing : (compressed + (255 - bitPos)) * spacing;
|
|
117
|
+
return { next, initialized };
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* `Pool.swap`, exact input, with the price limit the V4Quoter and the UniversalRouter use when none is given (the edge of
|
|
121
|
+
* the price range). `lpFeePips` is the swap's LP fee (a FLOOR pool overrides it to 2,500 on every swap).
|
|
122
|
+
*/
|
|
123
|
+
export function v4SwapExactIn(pool, zeroForOne, amountIn, lpFeePips, sqrtPriceLimitX96) {
|
|
124
|
+
if (amountIn <= 0n)
|
|
125
|
+
throw new RangeError('v4SwapExactIn: amountIn must be positive');
|
|
126
|
+
const limit = sqrtPriceLimitX96 ?? (zeroForOne ? MIN_SQRT + 1n : MAX_SQRT - 1n);
|
|
127
|
+
const protocolFee = BigInt(zeroForOne ? pool.protocolFee & 0xfff : (pool.protocolFee >> 12) & 0xfff);
|
|
128
|
+
const swapFee = protocolFee === 0n ? lpFeePips : protocolFee + lpFeePips - (protocolFee * lpFeePips) / MAX_SWAP_FEE;
|
|
129
|
+
if (swapFee >= MAX_SWAP_FEE)
|
|
130
|
+
throw new RangeError('v4SwapExactIn: a 100% fee leaves nothing to swap');
|
|
131
|
+
let remaining = amountIn;
|
|
132
|
+
let out = 0n;
|
|
133
|
+
let lpFee = 0n;
|
|
134
|
+
let toProtocol = 0n;
|
|
135
|
+
let sqrtP = pool.sqrtPriceX96;
|
|
136
|
+
let tick = pool.tick;
|
|
137
|
+
let liquidity = pool.liquidity;
|
|
138
|
+
while (remaining !== 0n && sqrtP !== limit) {
|
|
139
|
+
const start = sqrtP;
|
|
140
|
+
let { next: tickNext, initialized } = nextInitializedTickWithinOneWord(pool.bitmap, tick, pool.tickSpacing, zeroForOne);
|
|
141
|
+
if (tickNext <= MIN_TICK)
|
|
142
|
+
tickNext = MIN_TICK;
|
|
143
|
+
if (tickNext >= MAX_TICK)
|
|
144
|
+
tickNext = MAX_TICK;
|
|
145
|
+
const sqrtNext = sqrtPriceAtTick(tickNext);
|
|
146
|
+
const target = zeroForOne ? (sqrtNext < limit ? limit : sqrtNext) : (sqrtNext > limit ? limit : sqrtNext);
|
|
147
|
+
const step = computeSwapStepExactIn(sqrtP, target, liquidity, remaining, swapFee);
|
|
148
|
+
sqrtP = step.sqrtNext;
|
|
149
|
+
remaining -= step.amountIn + step.feeAmount;
|
|
150
|
+
out += step.amountOut;
|
|
151
|
+
let fee = step.feeAmount;
|
|
152
|
+
if (protocolFee > 0n) {
|
|
153
|
+
const delta = swapFee === protocolFee ? fee : ((step.amountIn + step.feeAmount) * protocolFee) / MAX_SWAP_FEE;
|
|
154
|
+
fee -= delta;
|
|
155
|
+
toProtocol += delta;
|
|
156
|
+
}
|
|
157
|
+
lpFee += fee;
|
|
158
|
+
if (sqrtP === sqrtNext) {
|
|
159
|
+
if (initialized) {
|
|
160
|
+
let net = pool.liquidityNet.get(tickNext) ?? 0n;
|
|
161
|
+
if (zeroForOne)
|
|
162
|
+
net = -net;
|
|
163
|
+
liquidity += net;
|
|
164
|
+
if (liquidity < 0n)
|
|
165
|
+
throw new RangeError('v4SwapExactIn: liquidity underflow (an inconsistent snapshot)');
|
|
166
|
+
}
|
|
167
|
+
tick = zeroForOne ? tickNext - 1 : tickNext;
|
|
168
|
+
}
|
|
169
|
+
else if (sqrtP !== start) {
|
|
170
|
+
tick = getTickAtSqrtPrice(sqrtP);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return { amountIn: amountIn - remaining, amountOut: out, lpFee, protocolFee: toProtocol, sqrtPriceX96: sqrtP, tick, liquidity };
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Quote an exact-input swap on a FLOOR pool. `side` is the trader's: `buy` pays `amountIn` of the quote for launch tokens,
|
|
177
|
+
* `sell` pays `amountIn` launch tokens for the quote. Throws `no_quote` when the pool cannot fill the whole
|
|
178
|
+
* input (the V4Quoter refuses such a swap too).
|
|
179
|
+
*/
|
|
180
|
+
export function simulateSwap(s, side, amountIn) {
|
|
181
|
+
if (amountIn <= 0n)
|
|
182
|
+
throw new RangeError('simulateSwap: amountIn must be positive');
|
|
183
|
+
const zeroForOne = side === 'buy' ? !s.quoteIsCurrency1 : s.quoteIsCurrency1;
|
|
184
|
+
const dearEdge = s.floorTick - bandTicks(s.pool.tickSpacing);
|
|
185
|
+
if (side === 'buy') {
|
|
186
|
+
const pre = marketTick(s.pool.tick, s.quoteIsCurrency1);
|
|
187
|
+
let bps = skimBpsAt('buy', dearEdge - pre, s.rates);
|
|
188
|
+
if (s.gapSkim)
|
|
189
|
+
bps = gapSkimBps(bps, s.cushion, pre);
|
|
190
|
+
const takes = hookTakes('buy', amountIn, bps, s.rates);
|
|
191
|
+
const toSwap = amountIn - takes.total;
|
|
192
|
+
const swap = toSwap > 0n ? v4SwapExactIn(s.pool, zeroForOne, toSwap, LP_FEE_PIPS) : null;
|
|
193
|
+
if (swap && swap.amountIn < toSwap)
|
|
194
|
+
throw new FloorEvmError('no_quote', `the pool fills ${swap.amountIn} of ${toSwap}`);
|
|
195
|
+
return {
|
|
196
|
+
side, amountIn, amountOut: swap?.amountOut ?? 0n, skimBps: bps,
|
|
197
|
+
fees: { lp: swap?.lpFee ?? 0n, protocol: swap?.protocolFee ?? 0n, floorSkim: takes.floorSkim, creator: takes.creator, holder: takes.holder, floorPlatform: takes.floorPlatform },
|
|
198
|
+
sqrtPriceX96After: swap?.sqrtPriceX96 ?? s.pool.sqrtPriceX96, tickAfter: swap?.tick ?? s.pool.tick, reachedBand: false,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
const swap = v4SwapExactIn(s.pool, zeroForOne, amountIn, LP_FEE_PIPS);
|
|
202
|
+
if (swap.amountIn < amountIn)
|
|
203
|
+
throw new FloorEvmError('no_quote', `the pool fills ${swap.amountIn} of ${amountIn}`);
|
|
204
|
+
const post = marketTick(swap.tick, s.quoteIsCurrency1);
|
|
205
|
+
const bps = skimBpsAt('sell', dearEdge - post, s.rates);
|
|
206
|
+
const takes = hookTakes('sell', swap.amountOut, bps, s.rates);
|
|
207
|
+
return {
|
|
208
|
+
side, amountIn, amountOut: swap.amountOut - takes.total, skimBps: bps,
|
|
209
|
+
fees: { lp: swap.lpFee, protocol: swap.protocolFee, floorSkim: takes.floorSkim, creator: takes.creator, holder: takes.holder, floorPlatform: takes.floorPlatform },
|
|
210
|
+
sqrtPriceX96After: swap.sqrtPriceX96, tickAfter: swap.tick, reachedBand: post >= dearEdge,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
// ---------------------------------------------------------------- reading a snapshot
|
|
214
|
+
/** Uniswap v4's StateView: the four reads a snapshot needs. */
|
|
215
|
+
export const STATE_VIEW_ABI = [
|
|
216
|
+
{ type: 'function', name: 'getSlot0', stateMutability: 'view', inputs: [{ name: 'poolId', type: 'bytes32' }], outputs: [{ name: 'sqrtPriceX96', type: 'uint160' }, { name: 'tick', type: 'int24' }, { name: 'protocolFee', type: 'uint24' }, { name: 'lpFee', type: 'uint24' }] },
|
|
217
|
+
{ type: 'function', name: 'getLiquidity', stateMutability: 'view', inputs: [{ name: 'poolId', type: 'bytes32' }], outputs: [{ name: 'liquidity', type: 'uint128' }] },
|
|
218
|
+
{ type: 'function', name: 'getTickBitmap', stateMutability: 'view', inputs: [{ name: 'poolId', type: 'bytes32' }, { name: 'tick', type: 'int16' }], outputs: [{ name: 'tickBitmap', type: 'uint256' }] },
|
|
219
|
+
{ type: 'function', name: 'getTickLiquidity', stateMutability: 'view', inputs: [{ name: 'poolId', type: 'bytes32' }, { name: 'tick', type: 'int24' }], outputs: [{ name: 'liquidityGross', type: 'uint128' }, { name: 'liquidityNet', type: 'int128' }] },
|
|
220
|
+
];
|
|
221
|
+
/**
|
|
222
|
+
* Read everything `simulateSwap` needs for one pool: the hook's `poolState` (rates, floor, orientation), the cushion, the
|
|
223
|
+
* PoolManager's slot0 and liquidity through StateView, the whole tick bitmap and every initialized tick's `liquidityNet`.
|
|
224
|
+
* About 120 bitmap reads plus one per initialized tick; batch them with a viem client that has `batch.multicall` set.
|
|
225
|
+
*/
|
|
226
|
+
export async function readSwapSnapshot(client, chainId, poolId) {
|
|
227
|
+
const d = floorDeploymentFor(chainId);
|
|
228
|
+
const hook = d.singletonHook;
|
|
229
|
+
if (!hook)
|
|
230
|
+
throw new FloorEvmError('bad_params', `chain ${chainId} has no singleton hook address`);
|
|
231
|
+
if (!d.stateView)
|
|
232
|
+
throw new FloorEvmError('bad_params', `chain ${chainId} has no StateView address`);
|
|
233
|
+
const sv = d.stateView;
|
|
234
|
+
const [st, cushion, slot0, liquidity] = await Promise.all([
|
|
235
|
+
readPoolState(client, hook, poolId),
|
|
236
|
+
readCushion(client, hook, poolId),
|
|
237
|
+
client.readContract({ address: sv, abi: STATE_VIEW_ABI, functionName: 'getSlot0', args: [poolId] }),
|
|
238
|
+
client.readContract({ address: sv, abi: STATE_VIEW_ABI, functionName: 'getLiquidity', args: [poolId] }),
|
|
239
|
+
]);
|
|
240
|
+
const spacing = Number(st.tickSpacing);
|
|
241
|
+
const minWord = compress(MIN_TICK, spacing) >> 8;
|
|
242
|
+
const maxWord = compress(MAX_TICK, spacing) >> 8;
|
|
243
|
+
const words = [];
|
|
244
|
+
for (let w = minWord; w <= maxWord; w++)
|
|
245
|
+
words.push(w);
|
|
246
|
+
const values = await Promise.all(words.map((w) => client.readContract({ address: sv, abi: STATE_VIEW_ABI, functionName: 'getTickBitmap', args: [poolId, w] })));
|
|
247
|
+
const bitmap = new Map();
|
|
248
|
+
const ticks = [];
|
|
249
|
+
words.forEach((w, i) => {
|
|
250
|
+
const word = values[i];
|
|
251
|
+
if (word === 0n)
|
|
252
|
+
return;
|
|
253
|
+
bitmap.set(w, word);
|
|
254
|
+
for (let bit = 0; bit < 256; bit++)
|
|
255
|
+
if ((word >> BigInt(bit)) & 1n)
|
|
256
|
+
ticks.push(((w << 8) + bit) * spacing);
|
|
257
|
+
});
|
|
258
|
+
const nets = await Promise.all(ticks.map((t) => client.readContract({ address: sv, abi: STATE_VIEW_ABI, functionName: 'getTickLiquidity', args: [poolId, t] })));
|
|
259
|
+
const liquidityNet = new Map();
|
|
260
|
+
ticks.forEach((t, i) => liquidityNet.set(t, nets[i][1]));
|
|
261
|
+
return {
|
|
262
|
+
pool: { sqrtPriceX96: slot0[0], tick: slot0[1], liquidity, tickSpacing: spacing, protocolFee: slot0[2], bitmap, liquidityNet },
|
|
263
|
+
quoteIsCurrency1: st.quoteIsCurrency1,
|
|
264
|
+
floorTick: Number(st.floorTick),
|
|
265
|
+
rates: poolRatesOf(st),
|
|
266
|
+
cushion,
|
|
267
|
+
gapSkim: rulesOf(d).gapSkim,
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
//# sourceMappingURL=simulate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simulate.js","sourceRoot":"","sources":["../src/simulate.ts"],"names":[],"mappings":"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"}
|
package/dist/trade.d.ts
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The calls a FLOOR trade on EVM is made of — the approvals it still needs, then the trade — as `EvmCall`s that
|
|
3
|
+
* `buildTrade` hands back in ONE `UnsignedTx` (one wallet prompt with EIP-5792, `sendEvmCalls`). Nothing here signs or
|
|
4
|
+
* sends; `pendingApprovals` is the one read.
|
|
5
|
+
*
|
|
6
|
+
* The four trades:
|
|
7
|
+
* - BONDING BUY (before graduation): `FloorLaunch.buy()` with the native amount as value, or `buy(amount)` with no value on a
|
|
8
|
+
* token-quoted sale after the quote is approved to the SALE (the exact amount by default). The amount is the GROSS cap (the sale's FLOOR Platform fee rides
|
|
9
|
+
* on top); the change is refunded. The buy that sells the sale out graduates it in the same transaction.
|
|
10
|
+
* - SELL-BACK (before graduation): `FloorToken.sellBack(tokens)` — pushed by the holder, no approval; pays in the quote
|
|
11
|
+
* what the contract version's rule gives (`sellBackQuote`), less the sale's FLOOR Platform fee.
|
|
12
|
+
* - POOL BUY / SELL (after graduation): one exact-in v4 swap through the chain's UniversalRouter, oriented by where the quote
|
|
13
|
+
* sits in the key, carrying a positive minimum received and a deadline. A token input is pulled through Permit2: the
|
|
14
|
+
* token's ERC-20 approval of Permit2 and Permit2's own ON-CHAIN `approve` of the router go in the same batch when missing.
|
|
15
|
+
* ⛔ No off-chain Permit2 signature (`signTypedData`) anywhere: it would be a second prompt.
|
|
16
|
+
* - The same pool swap through `FloorSwapRatchet`, which can run a due ratchet in the same transaction (opt-in).
|
|
17
|
+
* ⛔ The bonding calls carry NO on-chain minimum: the sale has none. `buildTrade` checks the quote against the caller's
|
|
18
|
+
* minimum at build time and refuses a trade that would not meet it; a buy racing another buy can still fill at a later
|
|
19
|
+
* tranche's price. The pool calls carry the minimum on chain (TAKE_ALL / `minOut`).
|
|
20
|
+
*/
|
|
21
|
+
import { type Address, type Hex } from 'viem';
|
|
22
|
+
import type { EvmCall, UnsignedTx } from '@floorlaunchpad/sdk';
|
|
23
|
+
import type { UrRelease } from './deployments.js';
|
|
24
|
+
/** The `unlimited` ERC-20 approval amount (2^255): one approval per token and spender, never re-asked. */
|
|
25
|
+
export declare const APPROVE_AMOUNT: bigint;
|
|
26
|
+
/**
|
|
27
|
+
* How much an approval grants: `exact` = the amount this trade spends (asked again next time), `unlimited` = 2^255 to a
|
|
28
|
+
* token's spender and Permit2's maximum to a Permit2 spender (asked once).
|
|
29
|
+
*/
|
|
30
|
+
export type ApprovalAmount = 'exact' | 'unlimited';
|
|
31
|
+
/** The default swap deadline: ten minutes from the moment the trade is built. */
|
|
32
|
+
export declare const SWAP_DEADLINE_SECONDS = 600n;
|
|
33
|
+
/**
|
|
34
|
+
* The gas limit every bonding buy is given while the sale is open: the buy that sells the sale out graduates the launch
|
|
35
|
+
* inline and needs ~3.6–3.9M gas on the Sepolia contracts (more with a team buy), and any buy can become that one if
|
|
36
|
+
* other buys land first — an estimate taken before them can sit far under it. A 5792 batch carries no gas limit (the
|
|
37
|
+
* wallet estimates the batch), so there the floor does not apply.
|
|
38
|
+
*/
|
|
39
|
+
export declare const BOND_BUY_GAS_FLOOR = 5100000n;
|
|
40
|
+
/** One user action's calls, in order, as `@floorlaunchpad/sdk`'s `UnsignedTx`. */
|
|
41
|
+
export declare function evmTx(chainId: number, calls: readonly EvmCall[]): UnsignedTx;
|
|
42
|
+
/** A bonding buy of GROSS `amountIn` of the sale's quote. `quote` null = native. */
|
|
43
|
+
export declare function buildBondBuy(a: {
|
|
44
|
+
launch: Address;
|
|
45
|
+
quote: Address | null;
|
|
46
|
+
amountIn: bigint;
|
|
47
|
+
}): EvmCall;
|
|
48
|
+
/** A sell-back of `tokens` to the sale (before graduation). Sent by the holder; no approval. */
|
|
49
|
+
export declare function buildSellBack(a: {
|
|
50
|
+
token: Address;
|
|
51
|
+
tokens: bigint;
|
|
52
|
+
}): EvmCall;
|
|
53
|
+
/** A graduated launch's pool, as a swap needs it. `poolId` is the HOOK's (`poolForAccount`); the key must hash to it. */
|
|
54
|
+
export interface PoolTarget {
|
|
55
|
+
token: Address;
|
|
56
|
+
hook: Address;
|
|
57
|
+
poolId: Hex;
|
|
58
|
+
/** The quote token; `null` = native. */
|
|
59
|
+
quote: Address | null;
|
|
60
|
+
quoteIsCurrency1: boolean;
|
|
61
|
+
}
|
|
62
|
+
export interface PoolSwapArgs extends PoolTarget {
|
|
63
|
+
side: 'buy' | 'sell';
|
|
64
|
+
/** Exact input: quote on a buy, tokens on a sell. */
|
|
65
|
+
amountIn: bigint;
|
|
66
|
+
/** The least received. Must be > 0. */
|
|
67
|
+
minOut: bigint;
|
|
68
|
+
/** Unix seconds. */
|
|
69
|
+
deadline: bigint;
|
|
70
|
+
router: {
|
|
71
|
+
address: Address;
|
|
72
|
+
release: UrRelease;
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/** A pool buy or sell through the chain's UniversalRouter. */
|
|
76
|
+
export declare function buildPoolSwap(a: PoolSwapArgs): EvmCall;
|
|
77
|
+
export interface SwapRatchetArgs extends PoolSwapArgs {
|
|
78
|
+
swapRatchet: Address;
|
|
79
|
+
/** Run the pool's ratchet after the swap when one is due (the keeper tip goes to the trader). */
|
|
80
|
+
ratchet: boolean;
|
|
81
|
+
/** Also sweep the pool's staircase fees after the swap (the sweep tip goes to the trader). Default false. */
|
|
82
|
+
sweep?: boolean;
|
|
83
|
+
}
|
|
84
|
+
/** The same pool swap through `FloorSwapRatchet.swapAndRatchet`: the contract pays the router, then ratchets when asked and
|
|
85
|
+
* due (the keeper tip goes to the trader). A token input is pulled by the RATCHET CONTRACT through Permit2. */
|
|
86
|
+
export declare function buildSwapRatchet(a: SwapRatchetArgs): EvmCall;
|
|
87
|
+
/** One approval a trade needs before it can be sent. `reader` is the contract whose allowance answers whether it is done. */
|
|
88
|
+
export interface ApprovalStep {
|
|
89
|
+
kind: 'erc20' | 'permit2';
|
|
90
|
+
call: EvmCall;
|
|
91
|
+
token: Address;
|
|
92
|
+
spender: Address;
|
|
93
|
+
/** The least allowance the trade spends (0 on a reset step). */
|
|
94
|
+
need: bigint;
|
|
95
|
+
/** A reset to 0 that `pendingApprovals` puts before an ERC-20 approval whose current allowance is above 0 but short. */
|
|
96
|
+
reset?: true;
|
|
97
|
+
/** ERC-20: the token (`allowance(owner, spender)`); Permit2: Permit2 (`allowance(owner, token, spender)`). */
|
|
98
|
+
reader: Address;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* What spending `token` through `spender` needs. Without Permit2: one ERC-20 approval of the spender. With Permit2: the
|
|
102
|
+
* token's approval of Permit2, then Permit2's own ON-CHAIN approval of the spender (max expiration). `amount`: `unlimited`
|
|
103
|
+
* (default) grants 2^255 / Permit2's maximum, `exact` grants `need`.
|
|
104
|
+
*/
|
|
105
|
+
export declare function tokenSpendApprovals(token: Address, spender: Address, permit2: Address | null, need: bigint, amount?: ApprovalAmount): ApprovalStep[];
|
|
106
|
+
/**
|
|
107
|
+
* A bonding buy's approvals: none on a native sale; the quote approved to the SALE (a per-launch contract) on a
|
|
108
|
+
* token-quoted one — the exact amount by default.
|
|
109
|
+
*/
|
|
110
|
+
export declare function bondBuyApprovals(a: {
|
|
111
|
+
launch: Address;
|
|
112
|
+
quote: Address | null;
|
|
113
|
+
amountIn: bigint;
|
|
114
|
+
}, amount?: ApprovalAmount): ApprovalStep[];
|
|
115
|
+
/**
|
|
116
|
+
* A pool swap's approvals. A native-quote buy needs none. Otherwise the input token is pulled through Permit2 by `spender`
|
|
117
|
+
* (the UniversalRouter, or the `FloorSwapRatchet` when the trade goes through it).
|
|
118
|
+
*/
|
|
119
|
+
export declare function poolSwapApprovals(a: {
|
|
120
|
+
side: 'buy' | 'sell';
|
|
121
|
+
token: Address;
|
|
122
|
+
quote: Address | null;
|
|
123
|
+
amountIn: bigint;
|
|
124
|
+
spender: Address;
|
|
125
|
+
permit2: Address | null;
|
|
126
|
+
}, amount?: ApprovalAmount): ApprovalStep[];
|
|
127
|
+
/**
|
|
128
|
+
* Reads each step's allowance for `owner` and returns the steps still short, in order. A failed read rejects (never
|
|
129
|
+
* "granted"). An ERC-20 approval whose current allowance is above 0 but short is preceded by an approval of 0 (`reset`):
|
|
130
|
+
* some tokens (USDT among them) refuse to move an allowance from one non-zero value to another.
|
|
131
|
+
*/
|
|
132
|
+
export declare function pendingApprovals(client: {
|
|
133
|
+
readContract(args: {
|
|
134
|
+
address: Address;
|
|
135
|
+
abi: readonly unknown[];
|
|
136
|
+
functionName: string;
|
|
137
|
+
args?: readonly unknown[];
|
|
138
|
+
}): Promise<unknown>;
|
|
139
|
+
}, owner: Address, steps: readonly ApprovalStep[], nowMs?: number): Promise<ApprovalStep[]>;
|
|
140
|
+
//# sourceMappingURL=trade.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trade.d.ts","sourceRoot":"","sources":["../src/trade.ts"],"names":[],"mappings":"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"}
|
package/dist/trade.js
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The calls a FLOOR trade on EVM is made of — the approvals it still needs, then the trade — as `EvmCall`s that
|
|
3
|
+
* `buildTrade` hands back in ONE `UnsignedTx` (one wallet prompt with EIP-5792, `sendEvmCalls`). Nothing here signs or
|
|
4
|
+
* sends; `pendingApprovals` is the one read.
|
|
5
|
+
*
|
|
6
|
+
* The four trades:
|
|
7
|
+
* - BONDING BUY (before graduation): `FloorLaunch.buy()` with the native amount as value, or `buy(amount)` with no value on a
|
|
8
|
+
* token-quoted sale after the quote is approved to the SALE (the exact amount by default). The amount is the GROSS cap (the sale's FLOOR Platform fee rides
|
|
9
|
+
* on top); the change is refunded. The buy that sells the sale out graduates it in the same transaction.
|
|
10
|
+
* - SELL-BACK (before graduation): `FloorToken.sellBack(tokens)` — pushed by the holder, no approval; pays in the quote
|
|
11
|
+
* what the contract version's rule gives (`sellBackQuote`), less the sale's FLOOR Platform fee.
|
|
12
|
+
* - POOL BUY / SELL (after graduation): one exact-in v4 swap through the chain's UniversalRouter, oriented by where the quote
|
|
13
|
+
* sits in the key, carrying a positive minimum received and a deadline. A token input is pulled through Permit2: the
|
|
14
|
+
* token's ERC-20 approval of Permit2 and Permit2's own ON-CHAIN `approve` of the router go in the same batch when missing.
|
|
15
|
+
* ⛔ No off-chain Permit2 signature (`signTypedData`) anywhere: it would be a second prompt.
|
|
16
|
+
* - The same pool swap through `FloorSwapRatchet`, which can run a due ratchet in the same transaction (opt-in).
|
|
17
|
+
* ⛔ The bonding calls carry NO on-chain minimum: the sale has none. `buildTrade` checks the quote against the caller's
|
|
18
|
+
* minimum at build time and refuses a trade that would not meet it; a buy racing another buy can still fill at a later
|
|
19
|
+
* tranche's price. The pool calls carry the minimum on chain (TAKE_ALL / `minOut`).
|
|
20
|
+
*/
|
|
21
|
+
import { encodeFunctionData, getAddress } from 'viem';
|
|
22
|
+
import { FLOOR_SWAP_RATCHET_ABI, LAUNCH_ABI, PERMIT2_ABI, TOKEN_ABI, UNIVERSAL_ROUTER_ABI } from './abi/index.js';
|
|
23
|
+
import { FloorEvmError } from './errors.js';
|
|
24
|
+
import { NATIVE, poolIdOfKey, poolKey, quoteAtCurrency1 } from './pool.js';
|
|
25
|
+
import { PERMIT2_MAX_AMOUNT, PERMIT2_MAX_EXPIRATION, encodeV4Swap, v4LayoutOf } from './router.js';
|
|
26
|
+
/** The `unlimited` ERC-20 approval amount (2^255): one approval per token and spender, never re-asked. */
|
|
27
|
+
export const APPROVE_AMOUNT = 2n ** 255n;
|
|
28
|
+
/** The default swap deadline: ten minutes from the moment the trade is built. */
|
|
29
|
+
export const SWAP_DEADLINE_SECONDS = 600n;
|
|
30
|
+
/**
|
|
31
|
+
* The gas limit every bonding buy is given while the sale is open: the buy that sells the sale out graduates the launch
|
|
32
|
+
* inline and needs ~3.6–3.9M gas on the Sepolia contracts (more with a team buy), and any buy can become that one if
|
|
33
|
+
* other buys land first — an estimate taken before them can sit far under it. A 5792 batch carries no gas limit (the
|
|
34
|
+
* wallet estimates the batch), so there the floor does not apply.
|
|
35
|
+
*/
|
|
36
|
+
export const BOND_BUY_GAS_FLOOR = 5100000n;
|
|
37
|
+
const isEvmAddress = (a) => typeof a === 'string' && /^0x[0-9a-fA-F]{40}$/.test(a) && !/^0x0{40}$/.test(a);
|
|
38
|
+
function positive(n, what) {
|
|
39
|
+
if (n <= 0n)
|
|
40
|
+
throw new FloorEvmError('bad_params', `${what}: the amount must be greater than zero`);
|
|
41
|
+
return n;
|
|
42
|
+
}
|
|
43
|
+
const call = (to, data, value = 0n) => ({ to, data, value });
|
|
44
|
+
/** One user action's calls, in order, as `@floorlaunchpad/sdk`'s `UnsignedTx`. */
|
|
45
|
+
export function evmTx(chainId, calls) {
|
|
46
|
+
if (calls.length === 0)
|
|
47
|
+
throw new FloorEvmError('bad_params', 'a transaction with no calls');
|
|
48
|
+
return { family: 'evm', chainId, calls };
|
|
49
|
+
}
|
|
50
|
+
/** A bonding buy of GROSS `amountIn` of the sale's quote. `quote` null = native. */
|
|
51
|
+
export function buildBondBuy(a) {
|
|
52
|
+
const amount = positive(a.amountIn, 'bond buy');
|
|
53
|
+
if (a.quote === null)
|
|
54
|
+
return call(a.launch, encodeFunctionData({ abi: LAUNCH_ABI, functionName: 'buy', args: [] }), amount);
|
|
55
|
+
return call(a.launch, encodeFunctionData({ abi: LAUNCH_ABI, functionName: 'buy', args: [amount] }));
|
|
56
|
+
}
|
|
57
|
+
/** A sell-back of `tokens` to the sale (before graduation). Sent by the holder; no approval. */
|
|
58
|
+
export function buildSellBack(a) {
|
|
59
|
+
return call(a.token, encodeFunctionData({ abi: TOKEN_ABI, functionName: 'sellBack', args: [positive(a.tokens, 'sell-back')] }));
|
|
60
|
+
}
|
|
61
|
+
function checkedKey(a, what) {
|
|
62
|
+
const quote = a.quote ?? NATIVE;
|
|
63
|
+
const key = poolKey(a.token, a.hook, quote);
|
|
64
|
+
if (poolIdOfKey(key).toLowerCase() !== a.poolId.toLowerCase())
|
|
65
|
+
throw new FloorEvmError('contract_mismatch', `${what}: the pool key does not hash to this launch's pool id`);
|
|
66
|
+
if (quoteAtCurrency1(key, quote) !== a.quoteIsCurrency1)
|
|
67
|
+
throw new FloorEvmError('contract_mismatch', `${what}: the quote orientation disagrees with the pool key`);
|
|
68
|
+
return { key, quote };
|
|
69
|
+
}
|
|
70
|
+
/** The UniversalRouter `execute` args for a pool swap. `payer: 'router'` when `FloorSwapRatchet` has paid the input in. */
|
|
71
|
+
function poolSwapPlan(a, payer) {
|
|
72
|
+
const what = `pool ${a.side}`;
|
|
73
|
+
const { key, quote } = checkedKey(a, what);
|
|
74
|
+
if (a.minOut <= 0n)
|
|
75
|
+
throw new FloorEvmError('bad_params', `${what}: the swap carries no minimum received`);
|
|
76
|
+
if (a.deadline <= 0n)
|
|
77
|
+
throw new FloorEvmError('bad_params', `${what}: the swap carries no deadline`);
|
|
78
|
+
const buying = a.side === 'buy';
|
|
79
|
+
const amountIn = positive(a.amountIn, what);
|
|
80
|
+
const zeroForOne = buying ? !a.quoteIsCurrency1 : a.quoteIsCurrency1;
|
|
81
|
+
const [currencyIn, currencyOut] = buying ? [quote, a.token] : [a.token, quote];
|
|
82
|
+
const plan = encodeV4Swap({ layout: v4LayoutOf('universal', a.router.release), key, zeroForOne, currencyIn, currencyOut, amountIn, minOut: a.minOut, payer });
|
|
83
|
+
const value = buying && a.quote === null ? amountIn : 0n;
|
|
84
|
+
return { plan, value, currencyIn, currencyOut, amountIn };
|
|
85
|
+
}
|
|
86
|
+
/** A pool buy or sell through the chain's UniversalRouter. */
|
|
87
|
+
export function buildPoolSwap(a) {
|
|
88
|
+
const { plan, value } = poolSwapPlan(a, 'user');
|
|
89
|
+
return call(a.router.address, encodeFunctionData({ abi: UNIVERSAL_ROUTER_ABI, functionName: 'execute', args: [plan.commands, [...plan.inputs], a.deadline] }), value);
|
|
90
|
+
}
|
|
91
|
+
/** The same pool swap through `FloorSwapRatchet.swapAndRatchet`: the contract pays the router, then ratchets when asked and
|
|
92
|
+
* due (the keeper tip goes to the trader). A token input is pulled by the RATCHET CONTRACT through Permit2. */
|
|
93
|
+
export function buildSwapRatchet(a) {
|
|
94
|
+
const { plan, value, currencyIn, currencyOut, amountIn } = poolSwapPlan(a, 'router');
|
|
95
|
+
const routerCalldata = encodeFunctionData({ abi: UNIVERSAL_ROUTER_ABI, functionName: 'execute', args: [plan.commands, [...plan.inputs], a.deadline] });
|
|
96
|
+
const s = { poolId: a.poolId, tokenIn: currencyIn, amountIn, tokenOut: currencyOut, minOut: a.minOut, routerCalldata, ratchet: a.ratchet, sweep: a.sweep ?? false };
|
|
97
|
+
const data = encodeFunctionData({ abi: FLOOR_SWAP_RATCHET_ABI, functionName: 'swapAndRatchet', args: [s] });
|
|
98
|
+
return call(a.swapRatchet, data, value);
|
|
99
|
+
}
|
|
100
|
+
function erc20Approval(token, spender, need, amount) {
|
|
101
|
+
return { kind: 'erc20', call: call(token, encodeFunctionData({ abi: TOKEN_ABI, functionName: 'approve', args: [spender, amount] })), token, spender, need, reader: token };
|
|
102
|
+
}
|
|
103
|
+
const erc20Amount = (need, amount) => (amount === 'exact' ? need : APPROVE_AMOUNT);
|
|
104
|
+
/**
|
|
105
|
+
* What spending `token` through `spender` needs. Without Permit2: one ERC-20 approval of the spender. With Permit2: the
|
|
106
|
+
* token's approval of Permit2, then Permit2's own ON-CHAIN approval of the spender (max expiration). `amount`: `unlimited`
|
|
107
|
+
* (default) grants 2^255 / Permit2's maximum, `exact` grants `need`.
|
|
108
|
+
*/
|
|
109
|
+
export function tokenSpendApprovals(token, spender, permit2, need, amount = 'unlimited') {
|
|
110
|
+
if (!isEvmAddress(token) || !isEvmAddress(spender))
|
|
111
|
+
throw new FloorEvmError('bad_params', 'approval: a token or spender is zero or malformed');
|
|
112
|
+
positive(need, 'approval');
|
|
113
|
+
if (!permit2)
|
|
114
|
+
return [erc20Approval(token, spender, need, erc20Amount(need, amount))];
|
|
115
|
+
if (amount === 'exact' && need > PERMIT2_MAX_AMOUNT)
|
|
116
|
+
throw new FloorEvmError('bad_params', `approval: ${need} is above Permit2's largest grant`);
|
|
117
|
+
const toPermit2 = erc20Approval(token, permit2, need, erc20Amount(need, amount));
|
|
118
|
+
return [
|
|
119
|
+
toPermit2,
|
|
120
|
+
{
|
|
121
|
+
kind: 'permit2',
|
|
122
|
+
call: call(permit2, encodeFunctionData({ abi: PERMIT2_ABI, functionName: 'approve', args: [token, spender, amount === 'exact' ? need : PERMIT2_MAX_AMOUNT, Number(PERMIT2_MAX_EXPIRATION)] })),
|
|
123
|
+
token, spender, need, reader: permit2,
|
|
124
|
+
},
|
|
125
|
+
];
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* A bonding buy's approvals: none on a native sale; the quote approved to the SALE (a per-launch contract) on a
|
|
129
|
+
* token-quoted one — the exact amount by default.
|
|
130
|
+
*/
|
|
131
|
+
export function bondBuyApprovals(a, amount = 'exact') {
|
|
132
|
+
return a.quote === null ? [] : [erc20Approval(a.quote, a.launch, a.amountIn, erc20Amount(a.amountIn, amount))];
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* A pool swap's approvals. A native-quote buy needs none. Otherwise the input token is pulled through Permit2 by `spender`
|
|
136
|
+
* (the UniversalRouter, or the `FloorSwapRatchet` when the trade goes through it).
|
|
137
|
+
*/
|
|
138
|
+
export function poolSwapApprovals(a, amount = 'unlimited') {
|
|
139
|
+
const buying = a.side === 'buy';
|
|
140
|
+
if (buying && a.quote === null)
|
|
141
|
+
return [];
|
|
142
|
+
const token = buying ? a.quote : a.token;
|
|
143
|
+
return tokenSpendApprovals(token, a.spender, a.permit2, a.amountIn, amount);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Reads each step's allowance for `owner` and returns the steps still short, in order. A failed read rejects (never
|
|
147
|
+
* "granted"). An ERC-20 approval whose current allowance is above 0 but short is preceded by an approval of 0 (`reset`):
|
|
148
|
+
* some tokens (USDT among them) refuse to move an allowance from one non-zero value to another.
|
|
149
|
+
*/
|
|
150
|
+
export async function pendingApprovals(client, owner, steps, nowMs = Date.now()) {
|
|
151
|
+
const out = [];
|
|
152
|
+
for (const s of steps) {
|
|
153
|
+
let have;
|
|
154
|
+
if (s.kind === 'erc20') {
|
|
155
|
+
have = (await client.readContract({ address: s.reader, abi: TOKEN_ABI, functionName: 'allowance', args: [getAddress(owner), s.spender] }));
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
const [amount, expiration] = (await client.readContract({ address: s.reader, abi: PERMIT2_ABI, functionName: 'allowance', args: [getAddress(owner), s.token, s.spender] }));
|
|
159
|
+
have = BigInt(expiration) * 1000n > BigInt(nowMs) ? amount : 0n;
|
|
160
|
+
}
|
|
161
|
+
if (have >= s.need)
|
|
162
|
+
continue;
|
|
163
|
+
if (s.kind === 'erc20' && have > 0n) {
|
|
164
|
+
out.push({ kind: 'erc20', call: call(s.token, encodeFunctionData({ abi: TOKEN_ABI, functionName: 'approve', args: [s.spender, 0n] })), token: s.token, spender: s.spender, need: 0n, reader: s.reader, reset: true });
|
|
165
|
+
}
|
|
166
|
+
out.push(s);
|
|
167
|
+
}
|
|
168
|
+
return out;
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=trade.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trade.js","sourceRoot":"","sources":["../src/trade.ts"],"names":[],"mappings":"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"}
|