@gangfun/cli 0.14.0 → 0.15.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 +1 -1
- package/README.zh-CN.md +1 -1
- package/package.json +1 -1
- package/src/bond.js +57 -23
- package/src/index.js +7 -4
package/README.md
CHANGED
|
@@ -227,4 +227,4 @@ gang agents --window 30d --sort follow
|
|
|
227
227
|
|
|
228
228
|
## Version
|
|
229
229
|
|
|
230
|
-
`0.
|
|
230
|
+
`0.15.0` · repo [gangfun/cli](https://github.com/gangfun/cli) · published to [npm](https://www.npmjs.com/package/@gangfun/cli) on push to `main`
|
package/README.zh-CN.md
CHANGED
|
@@ -200,4 +200,4 @@ gang agents --window 30d --sort follow
|
|
|
200
200
|
|
|
201
201
|
## 版本
|
|
202
202
|
|
|
203
|
-
`0.
|
|
203
|
+
`0.15.0` · [gangfun/cli](https://github.com/gangfun/cli) · push 到 `main` 自动发布到 [npm](https://www.npmjs.com/package/@gangfun/cli)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gangfun/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "Gang launchpad CLI for Binance Agentic Wallet agents: create on GangLaunchpad (untaxed or tax tokens), 打新 fair mint, PancakeSwap pool trades, LaunchpadV2 and legacy Soft/U/S trade.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/bond.js
CHANGED
|
@@ -15,11 +15,12 @@ import { bawAddress } from './baw.js'
|
|
|
15
15
|
* Env: GANG_BOND (mainnet), GANG_TESTNET_BOND (testnet) override the addresses below.
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
// script/DeployGangBond.s.sol. Testnet: 2026-10-
|
|
19
|
-
//
|
|
20
|
-
// without the notice; docs/TESTNET-GANG-BOND-2026-10-28.md). Mainnet: not deployed
|
|
18
|
+
// script/DeployGangBond.s.sol. Testnet: 2026-10-29, block 139463214, over the set-10 pad — the audited version (two-step
|
|
19
|
+
// settle, one buy-back chunk per 4 minutes; earlier testnet versions: 0x587f…5d7E after the pair only, 0x5a99…d716
|
|
20
|
+
// without the refund notice, 0xB034…EBE3 before the audit; docs/TESTNET-GANG-BOND-2026-10-28.md). Mainnet: not deployed
|
|
21
|
+
// yet (GANG_BOND overrides either)
|
|
21
22
|
export const MAINNET_BOND = null
|
|
22
|
-
export const TESTNET_BOND = '
|
|
23
|
+
export const TESTNET_BOND = '0xd6a8dd5d1E6641a34A255f25Db2B3ED397CB1086'
|
|
23
24
|
|
|
24
25
|
export const BOND_ABI = parseAbi([
|
|
25
26
|
'function post(address token, uint256 amount, uint256 holdAmount, uint64 duration) payable',
|
|
@@ -28,11 +29,12 @@ export const BOND_ABI = parseAbi([
|
|
|
28
29
|
'function extend(address token, uint64 by)',
|
|
29
30
|
'function start(address token)',
|
|
30
31
|
'function report(address token)',
|
|
32
|
+
'function requestSettle(address token)',
|
|
31
33
|
'function settle(address token)',
|
|
32
34
|
'function requestRefund(address token)',
|
|
33
35
|
'function refund(address token)',
|
|
34
36
|
'function burnChunk(address token, uint256 minTokensOut) returns (uint256 quoteIn, uint256 burned)',
|
|
35
|
-
'function bondOf(address token) view returns ((address creator, uint64 postedAt, uint32 round, address quote, uint8 state, uint64 deadline, uint64 duration, uint64
|
|
37
|
+
'function bondOf(address token) view returns ((address creator, uint64 postedAt, uint32 round, address quote, uint8 state, uint64 deadline, uint64 duration, uint64 requestAt, uint128 amount, uint128 holdAmount, uint128 burnLeft))',
|
|
36
38
|
'function isViolated(address token) view returns (bool)',
|
|
37
39
|
'function isLive(address token) view returns (bool)',
|
|
38
40
|
'function dumpValue(address token) view returns (uint256)',
|
|
@@ -42,12 +44,14 @@ export const BOND_ABI = parseAbi([
|
|
|
42
44
|
'function previewBurn(address token) view returns (bool ready, uint256 quoteIn, uint256 tokensOut)',
|
|
43
45
|
'function MIN_DURATION() view returns (uint64)', 'function MAX_DURATION() view returns (uint64)',
|
|
44
46
|
'function REPORTER_BPS() view returns (uint256)', 'function MAX_WAIT() view returns (uint64)', 'function REFUND_NOTICE() view returns (uint64)',
|
|
47
|
+
'function SETTLE_DELAY() view returns (uint64)', 'function CHUNK_GAP() view returns (uint64)',
|
|
45
48
|
'event BondPosted(address indexed token, address indexed creator, uint32 round, address quote, uint256 amount, uint256 holdAmount, uint64 duration, uint64 deadline)',
|
|
46
49
|
'event BondStarted(address indexed token, uint32 round, uint64 deadline)',
|
|
47
50
|
'event BondToppedUp(address indexed token, uint32 round, uint256 added, uint256 amount)',
|
|
48
51
|
'event HoldRaised(address indexed token, uint32 round, uint256 holdAmount)',
|
|
49
52
|
'event BondExtended(address indexed token, uint32 round, uint64 duration, uint64 deadline)',
|
|
50
53
|
'event BondReported(address indexed token, uint32 round, address indexed reporter, uint256 balance, uint256 reward, uint256 burnLeft)',
|
|
54
|
+
'event SettleRequested(address indexed token, uint32 round, uint64 settleAt)',
|
|
51
55
|
'event BondSettled(address indexed token, uint32 round, address indexed creator, uint256 amount)',
|
|
52
56
|
'event RefundRequested(address indexed token, uint32 round, uint64 refundAt)',
|
|
53
57
|
'event BondRefunded(address indexed token, uint32 round, address indexed creator, uint256 amount)',
|
|
@@ -55,7 +59,8 @@ export const BOND_ABI = parseAbi([
|
|
|
55
59
|
'error ZeroAddress()', 'error UnknownToken()', 'error NotTradable()', 'error NotCreator()', 'error BondLive()',
|
|
56
60
|
'error NotActive()', 'error ZeroAmount()', 'error BadDuration()', 'error BadHold()', 'error BadValue()',
|
|
57
61
|
'error FeeOnTransferQuote()', 'error NotViolated()', 'error Violated()', 'error NotDue()', 'error NothingToBurn()',
|
|
58
|
-
'error
|
|
62
|
+
'error BurnTooSoon()', 'error Slippage()', 'error FlashSwapActive()', 'error AlreadyLive()', 'error AlreadyRequested()', 'error NoRefundRequest()',
|
|
63
|
+
'error NoSettleRequest()',
|
|
59
64
|
'error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value)', 'error SafeERC20FailedOperation(address token)',
|
|
60
65
|
])
|
|
61
66
|
|
|
@@ -78,19 +83,21 @@ const HINTS = {
|
|
|
78
83
|
FeeOnTransferQuote: 'the quote takes a fee on transfer: it cannot be used for a bond',
|
|
79
84
|
NotViolated: 'the creator still holds at least X: nothing to report',
|
|
80
85
|
Violated: 'the creator holds less than X: the bond cannot be settled or refunded, only reported',
|
|
86
|
+
NoSettleRequest: 'ask to settle first (gang bond settle asks; it runs 1 hour later)',
|
|
81
87
|
AlreadyLive: 'the token reached its pair: the bond runs (gang bond start) instead of being refunded',
|
|
82
|
-
AlreadyRequested: '
|
|
88
|
+
AlreadyRequested: 'already requested: a refund runs once its 3-day notice is over, a settle 1 hour after its request',
|
|
83
89
|
NoRefundRequest: 'request the refund first (gang bond refund asks for it; it runs 3 days later)',
|
|
84
|
-
NotDue: 'the deadline has not passed
|
|
90
|
+
NotDue: 'not due yet: the deadline, the refund notice or the 1-hour settle wait has not passed',
|
|
85
91
|
NothingToBurn: 'no slashed bond with buy-back left on this token',
|
|
86
|
-
|
|
92
|
+
BurnTooSoon: 'a chunk was bought for this token less than 4 minutes ago: one chunk per 4 minutes',
|
|
87
93
|
Slippage: 'the buy-back would burn fewer tokens than the minimum: the price moved, re-run',
|
|
88
|
-
FlashSwapActive: 'the token\'s pair is mid flash swap: settle cannot count tokens borrowed from it; send
|
|
94
|
+
FlashSwapActive: 'the token\'s pair is mid flash swap: settle cannot count tokens borrowed from it; send it in its own tx',
|
|
89
95
|
}
|
|
90
96
|
|
|
91
97
|
const STATES = ['none', 'active', 'slashed', 'settled', 'refunded']
|
|
92
98
|
const MAX_WAIT = 30 * 86_400 // GangBond.MAX_WAIT
|
|
93
99
|
const REFUND_NOTICE = 3 * 86_400 // GangBond.REFUND_NOTICE
|
|
100
|
+
const SETTLE_DELAY = 3_600 // GangBond.SETTLE_DELAY
|
|
94
101
|
const BPS = 10_000n
|
|
95
102
|
const TOTAL_SUPPLY = 1_000_000_000n * 10n ** 18n
|
|
96
103
|
const DAY = 86_400
|
|
@@ -194,12 +201,12 @@ async function bondView(ctx, token, m) {
|
|
|
194
201
|
...(m.live
|
|
195
202
|
? { note: `the token is on its pair: anyone can start the clock (gang bond start --token ${token}); any other bond write starts it too` }
|
|
196
203
|
: { refundRequestFrom: new Date(refundAt * 1000).toISOString(), coverageNote: 'no coverage before the pair: shown once it trades on PancakeSwap' }),
|
|
197
|
-
...(b.
|
|
198
|
-
refundRequested: true, refundRunsAt: new Date(Number(b.
|
|
204
|
+
...(b.requestAt !== 0n && !m.live && {
|
|
205
|
+
refundRequested: true, refundRunsAt: new Date(Number(b.requestAt) * 1000).toISOString(),
|
|
199
206
|
refundNote: 'the creator asked for the bond back: it can be withdrawn from refundRunsAt if the token still has no pair; the promise binds until then, and graduation / launch cancels the request',
|
|
200
207
|
}),
|
|
201
208
|
...violatedNote,
|
|
202
|
-
...(!violated && !m.live && raw.now >= refundAt && b.
|
|
209
|
+
...(!violated && !m.live && raw.now >= refundAt && b.requestAt === 0n && { note: `no pair within 30 days of the post and X is held: the creator can ask for the bond back (gang bond refund --token ${token}); it runs 3 days later` }),
|
|
203
210
|
})
|
|
204
211
|
return { ...v, _raw: raw }
|
|
205
212
|
}
|
|
@@ -208,12 +215,20 @@ async function bondView(ctx, token, m) {
|
|
|
208
215
|
ctx.read(ctx.bond, BOND_ABI, 'coverageBps', [token]),
|
|
209
216
|
])
|
|
210
217
|
const left = Number(b.deadline) - now
|
|
218
|
+
const settleAt = Number(b.requestAt)
|
|
211
219
|
Object.assign(v, {
|
|
212
220
|
phase: 'running', violated, dumpValue: q(dump), coveragePct: cov === MAX_UINT ? null : pctOfBps(cov), tier: tierOf(cov), tierNote: TIER_NOTE[tierOf(cov)],
|
|
213
221
|
toFullCover: dump > b.amount ? q(dump - b.amount) : '0',
|
|
214
222
|
...(left > 0 ? { secondsLeft: left, daysLeft: Math.round((left / DAY) * 10) / 10 } : { pastDeadline: true }),
|
|
215
223
|
...violatedNote,
|
|
216
|
-
...(
|
|
224
|
+
...(settleAt !== 0 && { settleRequested: true, settleRunsAt: new Date(settleAt * 1000).toISOString() }),
|
|
225
|
+
...(!violated && left <= 0 && {
|
|
226
|
+
note: settleAt === 0
|
|
227
|
+
? `past the deadline and X is held: anyone can settle it in two steps (gang bond settle --token ${token} asks; run it again 1 hour later and the bond goes back to the creator). X must still be held then; until then it can be reported if the balance drops below X`
|
|
228
|
+
: now < settleAt
|
|
229
|
+
? `settle asked for: it runs from settleRunsAt if X is still held then; until then it can be reported if the balance drops below X`
|
|
230
|
+
: `settle is due: gang bond settle --token ${token} returns the bond to the creator (X must still be held)`,
|
|
231
|
+
}),
|
|
217
232
|
})
|
|
218
233
|
Object.assign(raw, { dump, cov })
|
|
219
234
|
}
|
|
@@ -227,7 +242,7 @@ async function bondView(ctx, token, m) {
|
|
|
227
242
|
? 'slashed before the pair and still no pair 30 days after the post: gang bond burn --token … sends the rest to 0xdead as quote'
|
|
228
243
|
: `slashed before the pair: the buy-back starts once the token ${m.kind === 'v3' ? 'graduates' : 'launches'}; if it has not by ${new Date((Number(b.postedAt) + MAX_WAIT) * 1000).toISOString()}, the rest goes to 0xdead as quote`,
|
|
229
244
|
}),
|
|
230
|
-
...(b.burnLeft > 0n && m.live && { nextChunk: ready ? { quoteIn: q(quoteIn), tokensOut: tokens(tokensOut) } : null, nextChunkNote: ready ? 'gang bond burn --token … buys this chunk now' : 'not ready: the first call after a slash records a price observation, then the buy-back waits 10 minutes and skips while the price is more than 2% above its average (after 20 minutes without a call it starts over)' }),
|
|
245
|
+
...(b.burnLeft > 0n && m.live && { nextChunk: ready ? { quoteIn: q(quoteIn), tokensOut: tokens(tokensOut) } : null, nextChunkNote: ready ? 'gang bond burn --token … buys this chunk now' : 'not ready: the first call after a slash records a price observation, then the buy-back waits 10 minutes and skips while the price is more than 2% above its average (after 20 minutes without a call it starts over); at most one chunk per 4 minutes' }),
|
|
231
246
|
})
|
|
232
247
|
}
|
|
233
248
|
return { ...v, _raw: raw }
|
|
@@ -350,7 +365,7 @@ export async function runBond(sub, { opt, flag, out, fail, summarize }) {
|
|
|
350
365
|
if (!same(me(), b.creator)) return fail('only the creator can ask for its bond back', { wallet: me(), creator: b.creator })
|
|
351
366
|
if (!raw.pending || m.live) return fail(HINTS.AlreadyLive, { deadline: view.deadline })
|
|
352
367
|
if (view.violated) return fail(HINTS.Violated, { creatorBalance: view.creatorBalance, holdTokens: view.holdTokens })
|
|
353
|
-
if (b.
|
|
368
|
+
if (b.requestAt === 0n) {
|
|
354
369
|
const requestAt = Number(b.postedAt) + MAX_WAIT
|
|
355
370
|
if (raw.now < requestAt) return fail('a refund can be asked for only 30 days after the post without a pair', { refundRequestFrom: view.refundRequestFrom, secondsLeft: requestAt - raw.now })
|
|
356
371
|
const sim = await simulate(ctx, me(), 'requestRefund', [token])
|
|
@@ -360,7 +375,7 @@ export async function runBond(sub, { opt, flag, out, fail, summarize }) {
|
|
|
360
375
|
note: 'step 1 of 2: starts a 3-day notice (shown on gang.fun). Keep holding X: a breach can still be reported, and if the token graduates / launches meanwhile the request is void and the clock starts. Then run gang bond refund again',
|
|
361
376
|
}))
|
|
362
377
|
}
|
|
363
|
-
if (raw.now < Number(b.
|
|
378
|
+
if (raw.now < Number(b.requestAt)) return fail('the refund notice is not over yet', { refundRunsAt: view.refundRunsAt, secondsLeft: Number(b.requestAt) - raw.now })
|
|
364
379
|
const sim = await simulate(ctx, me(), 'refund', [token])
|
|
365
380
|
if (sim.failed) return out({ success: false, step: 'refund', ...sim.failed })
|
|
366
381
|
return out(send('refund', [token], { step: 'refund', refund: view.bond, quote: view.quote, note: 'step 2 of 2: no pair after the notice, X held: the bond comes back to you (not counted as honored)' }))
|
|
@@ -375,9 +390,19 @@ export async function runBond(sub, { opt, flag, out, fail, summarize }) {
|
|
|
375
390
|
}
|
|
376
391
|
if (raw.now < Number(b.deadline)) return fail(HINTS.NotDue, { deadline: view.deadline, secondsLeft: Number(b.deadline) - raw.now })
|
|
377
392
|
if (view.violated) return fail(HINTS.Violated, { creatorBalance: view.creatorBalance, holdTokens: view.holdTokens, hint: `gang bond report --token ${token}${net}` })
|
|
393
|
+
// two steps, anyone: ask (X held now), then settle 1 hour later (X held again) — so X can't be met for one tx only
|
|
394
|
+
if (b.requestAt === 0n) {
|
|
395
|
+
const sim = await simulate(ctx, me(), 'requestSettle', [token])
|
|
396
|
+
if (sim.failed) return out({ success: false, step: 'request-settle', ...sim.failed })
|
|
397
|
+
return out(send('requestSettle', [token], {
|
|
398
|
+
step: 'request-settle', creator: b.creator, bond: view.bond, quote: view.quote, settleRunsAbout: new Date((raw.now + SETTLE_DELAY) * 1000).toISOString(),
|
|
399
|
+
note: 'step 1 of 2: the bond can be settled 1 hour after this lands, if the creator still holds X then; until then a drop below X can be reported. Then run gang bond settle again',
|
|
400
|
+
}))
|
|
401
|
+
}
|
|
402
|
+
if (raw.now < Number(b.requestAt)) return fail('the settle wait is not over yet', { settleRunsAt: view.settleRunsAt, secondsLeft: Number(b.requestAt) - raw.now })
|
|
378
403
|
const sim = await simulate(ctx, me(), 'settle', [token])
|
|
379
404
|
if (sim.failed) return out({ success: false, step: 'settle', ...sim.failed })
|
|
380
|
-
return out(send('settle', [token], { step: 'settle', creator: b.creator, refund: view.bond, quote: view.quote, note: 'the bond goes back to the creator, whoever sends this' }))
|
|
405
|
+
return out(send('settle', [token], { step: 'settle', creator: b.creator, refund: view.bond, quote: view.quote, note: 'step 2 of 2: the bond goes back to the creator, whoever sends this' }))
|
|
381
406
|
}
|
|
382
407
|
|
|
383
408
|
if (sub === 'burn') {
|
|
@@ -394,7 +419,7 @@ export async function runBond(sub, { opt, flag, out, fail, summarize }) {
|
|
|
394
419
|
step: 'burn', burnLeft: view.burnLeft, quote: view.quote,
|
|
395
420
|
...(toDead ? { quoteToDead: qf(quoteIn), note: 'slashed before the pair and still no pair 30 days after the post: the rest goes to 0xdead as quote' }
|
|
396
421
|
: ready ? { chunkQuoteIn: qf(quoteIn), expectBurnTokens: tokens(tokensOut), minBurnTokens: tokens(minOut), slippagePct: slippage }
|
|
397
|
-
: { note: 'no chunk this time: the call records the price observation (first call after a slash) or waits for the 10-minute average / a price no more than 2% above it. It is cheap; the platform keeper also calls it every
|
|
422
|
+
: { note: 'no chunk this time: the call records the price observation (first call after a slash) or waits for the 10-minute average / a price no more than 2% above it. It is cheap; the platform keeper also calls it every 5 minutes (one chunk per 4 minutes at most). If a chunk becomes buyable before it lands, it reverts (Slippage) rather than buy without a minimum: re-run then' }),
|
|
398
423
|
}))
|
|
399
424
|
}
|
|
400
425
|
|
|
@@ -515,7 +540,8 @@ export async function runBond(sub, { opt, flag, out, fail, summarize }) {
|
|
|
515
540
|
* bond, not the creator), else one of:
|
|
516
541
|
* - { refuse: {…} } — the sell would leave less than X before the deadline (no --break-bond), or after the deadline
|
|
517
542
|
* before settle (no --settle-first): print it as the failure;
|
|
518
|
-
* - { settleStep: {…} } — --settle-first after the deadline: send this
|
|
543
|
+
* - { settleStep: {…} } — --settle-first after the deadline: send this step first (ask to settle, or settle once the
|
|
544
|
+
* 1-hour wait is over), then re-run the sell;
|
|
519
545
|
* - { info: {…} } — go on, with these fields added to the preview (headroom after the sell, or the --break-bond warning).
|
|
520
546
|
*/
|
|
521
547
|
export async function bondGuard(ctx, p, rawOnly, summarize) {
|
|
@@ -549,10 +575,18 @@ export async function bondGuard(ctx, p, rawOnly, summarize) {
|
|
|
549
575
|
const net = p.testnet ? ' --testnet' : ''
|
|
550
576
|
if (pastDeadline && bal >= b.holdAmount) {
|
|
551
577
|
if (!p.settleFirst) {
|
|
552
|
-
return { refuse: { error: `the bond is past its deadline but not settled: this sell leaves ${tokens(after)} tokens, below X (${tokens(b.holdAmount)}), and anyone could report it before you settle`, ...base, hint: `run gang bond settle --token ${p.token}${net} first, or add --settle-first to this sell` } }
|
|
578
|
+
return { refuse: { error: `the bond is past its deadline but not settled: this sell leaves ${tokens(after)} tokens, below X (${tokens(b.holdAmount)}), and anyone could report it before you settle`, ...base, hint: `run gang bond settle --token ${p.token}${net} first (two steps, 1 hour apart), or add --settle-first to this sell` } }
|
|
579
|
+
}
|
|
580
|
+
const now = Number(block.timestamp)
|
|
581
|
+
if (b.requestAt !== 0n && now < Number(b.requestAt)) {
|
|
582
|
+
return { refuse: { error: 'settle is asked for but its 1-hour wait is not over: keep X until it runs, then settle and sell', ...base, settleRunsAt: new Date(Number(b.requestAt) * 1000).toISOString(), secondsLeft: Number(b.requestAt) - now } }
|
|
553
583
|
}
|
|
554
|
-
const
|
|
555
|
-
|
|
584
|
+
const fn = b.requestAt === 0n ? 'requestSettle' : 'settle'
|
|
585
|
+
const data = encodeFunctionData({ abi: BOND_ABI, functionName: fn, args: [p.token] })
|
|
586
|
+
const note = fn === 'requestSettle'
|
|
587
|
+
? 'ask to settle first (step 1 of 2): 1 hour after it lands, settle (the bond comes back to you) and then sell; keep X until then'
|
|
588
|
+
: 'settle first (the bond comes back to you); after executing, re-run the same sell'
|
|
589
|
+
return { settleStep: step(ctx, { from: p.me, to: addr, data }, { step: fn === 'requestSettle' ? 'request-settle' : 'settle', chainId: Number(ctx.chainId), token: p.token, refund: base.bond, ...base, note }, rawOnly, summarize) }
|
|
556
590
|
}
|
|
557
591
|
const lost = formatUnits(b.amount, dec)
|
|
558
592
|
const consequence = `anyone can report it, the reporter takes 1% and the rest of the ${lost} bond buys back and burns the token`
|
package/src/index.js
CHANGED
|
@@ -315,7 +315,8 @@ graduated tokens only).
|
|
|
315
315
|
a reverted simulation with --calldata is doNotSend: true, no tx. V2 / Soft / U / S:
|
|
316
316
|
--from only on graduated tokens, mainnet only
|
|
317
317
|
A creator selling below its bonded X (gang bond) is refused unless --break-bond;
|
|
318
|
-
past the deadline, --settle-first settles the bond before the sell
|
|
318
|
+
past the deadline, --settle-first settles the bond before the sell (asks first;
|
|
319
|
+
settles 1 hour later).
|
|
319
320
|
|
|
320
321
|
BOND (押金承诺, GangBond; any GangLaunchpad token, from create on; GANG_BOND / GANG_TESTNET_BOND = its address):
|
|
321
322
|
gang bond post --token <addr> --hold <tokens|N%> --days <7-90> (--amount <quote> | --cover <coverage %>) [--use-wbnb]
|
|
@@ -335,13 +336,15 @@ BOND (押金承诺, GangBond; any GangLaunchpad token, from create on; GANG_BOND
|
|
|
335
336
|
gang bond start --token <addr> anyone, once the token graduated / launched: start the clock (deadline = now + days)
|
|
336
337
|
gang bond report --token <addr> anyone, when the creator holds less than X: 1% of the bond to you, the rest buys
|
|
337
338
|
back and burns the token (simulated first; nothing is sent when not violated)
|
|
338
|
-
gang bond settle --token <addr> anyone, after the deadline while X is held:
|
|
339
|
+
gang bond settle --token <addr> anyone, after the deadline while X is held, two steps: run it once to ask, again
|
|
340
|
+
1 hour later (X still held) and the bond goes back to the creator
|
|
339
341
|
gang bond refund --token <addr> creator, posted before the pair and still no pair 30 days later: run it once to ask
|
|
340
342
|
(a 3-day notice: X still binds, graduation / launch voids it), again after it to
|
|
341
343
|
get the bond back
|
|
342
344
|
gang bond burn --token <addr> [--slippage 1]
|
|
343
|
-
anyone: one buy-back chunk of a slashed bond (≤ 0.5% of the pair's quote side
|
|
344
|
-
for a 10-minute average and skips when the price is > 2% above
|
|
345
|
+
anyone: one buy-back chunk of a slashed bond (≤ 0.5% of the pair's quote side, one
|
|
346
|
+
per 4 minutes; waits for a 10-minute average and skips when the price is > 2% above
|
|
347
|
+
it). Slashed before the
|
|
345
348
|
pair: waits for it; none 30 days after the post → the rest goes to 0xdead as quote
|
|
346
349
|
gang bond tx --hash <0x..> decode GangBond events. --testnet, --calldata, --from as in gang v3. A bonded
|
|
347
350
|
creator's gang v3 sell (curve or pool), gang fair sell and gang fair withdraw are
|