@black-market/sdk 0.10.0 → 0.12.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 +21 -2
- package/dist/lifecycle/abi.d.ts +1 -0
- package/dist/lifecycle/abi.d.ts.map +1 -1
- package/dist/lifecycle/abi.js +1 -0
- package/dist/lifecycle/abi.js.map +1 -1
- package/dist/lifecycle/calibration.d.ts.map +1 -1
- package/dist/lifecycle/calibration.js +2 -0
- package/dist/lifecycle/calibration.js.map +1 -1
- package/dist/lifecycle/deployments/ufg-dynamic-pool-20261021.d.ts +71 -0
- package/dist/lifecycle/deployments/ufg-dynamic-pool-20261021.d.ts.map +1 -0
- package/dist/lifecycle/deployments/ufg-dynamic-pool-20261021.js +73 -0
- package/dist/lifecycle/deployments/ufg-dynamic-pool-20261021.js.map +1 -0
- package/dist/lifecycle/deployments/ufg-fixed-pool-20261021.d.ts +71 -0
- package/dist/lifecycle/deployments/ufg-fixed-pool-20261021.d.ts.map +1 -0
- package/dist/lifecycle/deployments/ufg-fixed-pool-20261021.js +73 -0
- package/dist/lifecycle/deployments/ufg-fixed-pool-20261021.js.map +1 -0
- package/dist/lifecycle/index.d.ts +1 -0
- package/dist/lifecycle/index.d.ts.map +1 -1
- package/dist/lifecycle/index.js +1 -0
- package/dist/lifecycle/index.js.map +1 -1
- package/dist/lifecycle/markets.d.ts +3 -1
- package/dist/lifecycle/markets.d.ts.map +1 -1
- package/dist/lifecycle/markets.js +20 -3
- package/dist/lifecycle/markets.js.map +1 -1
- package/dist/lifecycle/planner.d.ts.map +1 -1
- package/dist/lifecycle/planner.js +83 -54
- package/dist/lifecycle/planner.js.map +1 -1
- package/dist/lifecycle/presets.d.ts +9 -2
- package/dist/lifecycle/presets.d.ts.map +1 -1
- package/dist/lifecycle/presets.js +26 -5
- package/dist/lifecycle/presets.js.map +1 -1
- package/dist/lifecycle/progress.d.ts.map +1 -1
- package/dist/lifecycle/progress.js +26 -5
- package/dist/lifecycle/progress.js.map +1 -1
- package/dist/lifecycle/rpc.js +3 -2
- package/dist/lifecycle/rpc.js.map +1 -1
- package/dist/lifecycle/simulation.d.ts +1 -1
- package/dist/lifecycle/simulation.d.ts.map +1 -1
- package/dist/lifecycle/simulation.js +119 -175
- package/dist/lifecycle/simulation.js.map +1 -1
- package/dist/lifecycle/transactions.d.ts +6 -0
- package/dist/lifecycle/transactions.d.ts.map +1 -1
- package/dist/lifecycle/transactions.js +39 -0
- package/dist/lifecycle/transactions.js.map +1 -1
- package/dist/lifecycle/types.d.ts +17 -4
- package/dist/lifecycle/types.d.ts.map +1 -1
- package/dist/lifecycle/types.js.map +1 -1
- package/dist/lifecycle/ufg-abi.d.ts +2386 -0
- package/dist/lifecycle/ufg-abi.d.ts.map +1 -0
- package/dist/lifecycle/ufg-abi.js +171 -0
- package/dist/lifecycle/ufg-abi.js.map +1 -0
- package/dist/lifecycle/ufg-config.d.ts +38 -0
- package/dist/lifecycle/ufg-config.d.ts.map +1 -0
- package/dist/lifecycle/ufg-config.js +75 -0
- package/dist/lifecycle/ufg-config.js.map +1 -0
- package/dist/lifecycle/ufg.d.ts +21 -0
- package/dist/lifecycle/ufg.d.ts.map +1 -0
- package/dist/lifecycle/ufg.js +98 -0
- package/dist/lifecycle/ufg.js.map +1 -0
- package/docs/launch-lifecycle.md +215 -32
- package/examples/.env.example +4 -0
- package/examples/README.md +35 -2
- package/examples/launch-example-support.ts +1 -0
- package/examples/launch-example.ts +1 -0
- package/examples/launch.ts +1 -0
- package/examples/ufg-launch-config.ts +31 -0
- package/package.json +1 -1
- package/src/lifecycle/abi.ts +1 -0
- package/src/lifecycle/calibration.ts +1 -0
- package/src/lifecycle/deployments/ufg-dynamic-pool-20261021.ts +74 -0
- package/src/lifecycle/deployments/ufg-fixed-pool-20261021.ts +74 -0
- package/src/lifecycle/index.ts +1 -0
- package/src/lifecycle/markets.ts +16 -3
- package/src/lifecycle/planner.ts +75 -51
- package/src/lifecycle/presets.ts +27 -6
- package/src/lifecycle/progress.ts +22 -5
- package/src/lifecycle/rpc.ts +3 -2
- package/src/lifecycle/simulation.ts +114 -166
- package/src/lifecycle/transactions.ts +38 -1
- package/src/lifecycle/types.ts +15 -5
- package/src/lifecycle/ufg-abi.ts +173 -0
- package/src/lifecycle/ufg-config.ts +77 -0
- package/src/lifecycle/ufg.ts +86 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { decodeFunctionResult, encodeFunctionData, keccak256, stringToHex, zeroAddress } from "viem";
|
|
2
|
+
import { lifecycleErc20Abi } from "./abi.js";
|
|
3
|
+
import { ufgLaunchProxyV1Abi, ufgTreasuryFactoryV1Abi } from "./ufg-abi.js";
|
|
4
|
+
import { buildLaunchTransactions } from "./transactions.js";
|
|
5
|
+
import { decodeAbyssLifecycleMarketConfig, encodeAbyssLifecycleMarketConfig, decodePoolBoundV4LifecycleMarketConfig } from "./markets.js";
|
|
6
|
+
import { getKnownLifecycleProfile, KnownLifecycleProfile } from "./presets.js";
|
|
7
|
+
import { LifecycleFundingKind, LifecycleTokenKind, LifecycleRewardMode, LifecycleMode } from "./schema.js";
|
|
8
|
+
import { LifecyclePlanningError } from "./types.js";
|
|
9
|
+
import { buildUfgFeeAssetPolicies, encodeUfgLaunchConfig, hashUfgLaunchConfig, isUfgProfile, UFG_DYNAMIC_ADAPTER_ID, UFG_FIXED_ADAPTER_ID, UFG_FIXED_PROFILE_ID, UFG_LAUNCH_PROXY_ADDRESS, UFG_TREASURY_FACTORY_ADDRESS, ufgPlanPrincipal } from "./ufg-config.js";
|
|
10
|
+
export { UFG_LAUNCH_PROXY_ADDRESS, UFG_TREASURY_FACTORY_ADDRESS, UFG_UPSTREAM_FACTORY_ADDRESS, UFG_ORCHESTRATOR_ADDRESS, UFG_FIXED_PROFILE_ID, UFG_DYNAMIC_PROFILE_ID, UFG_FIXED_ADAPTER_ID, UFG_DYNAMIC_ADAPTER_ID, isUfgProfile, ufgLaunchConfigComponents, encodeUfgLaunchConfig, decodeUfgLaunchConfig, hashUfgLaunchConfig, validateUfgLaunchConfig, ufgLaunchNonce, buildUfgFeeAssetPolicies } from "./ufg-config.js";
|
|
11
|
+
/** Offline proxy-specific admission. Live token/reserve code, registry and transfer checks still require simulation. */
|
|
12
|
+
export function validateUfgLaunchPlan(plan, config, predictedToken) {
|
|
13
|
+
try {
|
|
14
|
+
ufgPlanPrincipal(plan);
|
|
15
|
+
encodeUfgLaunchConfig(config);
|
|
16
|
+
if (plan.token.kind !== LifecycleTokenKind.ERC20 || plan.token.rewardMode !== LifecycleRewardMode.None || plan.executorFeeBps !== 0 || plan.markets.length === 0 || plan.token.inventoryRecipient.toLowerCase() === UFG_LAUNCH_PROXY_ADDRESS.toLowerCase() || plan.buys.some((buy) => buy.recipient.toLowerCase() === UFG_LAUNCH_PROXY_ADDRESS.toLowerCase()))
|
|
17
|
+
throw new Error("UFG requires ERC20/no rewards, zero executor fee, markets and external inventory/buy recipients");
|
|
18
|
+
const expected = buildUfgFeeAssetPolicies(predictedToken, config.reserveAssets);
|
|
19
|
+
if (plan.feeAssets.length !== expected.length || plan.feeAssets.some((policy, index) => {
|
|
20
|
+
const required = expected[index];
|
|
21
|
+
return policy.asset.toLowerCase() !== required.asset.toLowerCase() || policy.ownerBps !== required.ownerBps || policy.rewardsBps !== 0 || policy.burnBps !== required.burnBps;
|
|
22
|
+
}))
|
|
23
|
+
throw new Error("UFG fee policies must burn all token fees and send all reserve fees to the owner, in ascending asset order");
|
|
24
|
+
const reserves = new Set(config.reserveAssets.map((asset) => asset.toLowerCase()));
|
|
25
|
+
const quotes = new Set(plan.markets.map((market) => market.quoteAsset.toLowerCase()));
|
|
26
|
+
if (reserves.size !== quotes.size || [...quotes].some((quote) => !reserves.has(quote)))
|
|
27
|
+
throw new Error("Every reserve must be a market quote and every market quote a reserve");
|
|
28
|
+
const configHash = hashUfgLaunchConfig(config);
|
|
29
|
+
for (const market of plan.markets) {
|
|
30
|
+
if (market.configVersion === 1) {
|
|
31
|
+
const inner = decodeAbyssLifecycleMarketConfig(market.config);
|
|
32
|
+
const profile = getKnownLifecycleProfile({ chainId: plan.chainId, orchestrator: plan.orchestrator, key: inner.profile === 2 ? KnownLifecycleProfile.Abyss2 : KnownLifecycleProfile.Abyss3 });
|
|
33
|
+
if (market.adapterId.toLowerCase() !== keccak256(stringToHex("black-market.adapter.abyss-lifecycle.v1")) || (inner.profile !== 2 && inner.profile !== 3) || market.profileId.toLowerCase() !== profile?.profile.id || encodeAbyssLifecycleMarketConfig(inner).toLowerCase() !== market.config.toLowerCase())
|
|
34
|
+
throw new Error("UFG Abyss markets require canonical QUOTE or QUOTE_ORACLE config1 without a tail");
|
|
35
|
+
}
|
|
36
|
+
else if (market.configVersion === 6) {
|
|
37
|
+
if (!isUfgProfile(market.profileId))
|
|
38
|
+
throw new Error("UFG config6 markets require an admitted UFG fixed or dynamic profile");
|
|
39
|
+
const inner = decodePoolBoundV4LifecycleMarketConfig(market.config, 6);
|
|
40
|
+
const adapterId = market.profileId.toLowerCase() === UFG_FIXED_PROFILE_ID ? UFG_FIXED_ADAPTER_ID : UFG_DYNAMIC_ADAPTER_ID;
|
|
41
|
+
if (market.adapterId.toLowerCase() !== adapterId || inner.profileId.toLowerCase() !== market.profileId.toLowerCase() || inner.version !== 6 || inner.feeMode !== 1 || inner.lpFeePips !== 0 || inner.ufgLaunchConfig === undefined || hashUfgLaunchConfig(inner.ufgLaunchConfig) !== configHash)
|
|
42
|
+
throw new Error("Every UFG config6 market requires QuoteOnly, zero LP fee and the identical canonical proxy config tail");
|
|
43
|
+
}
|
|
44
|
+
else
|
|
45
|
+
throw new Error("UFG supports only canonical Abyss config1 and UFG pool-bound config6");
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
if (error instanceof LifecyclePlanningError && error.code === "INVALID_UFG_PLAN")
|
|
50
|
+
throw error;
|
|
51
|
+
throw new LifecyclePlanningError("INVALID_UFG_PLAN", error instanceof Error ? error.message : "Invalid UFG launch plan");
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/** Pure unsigned proxy commands; account is the principal encoded in plan.nonce. */
|
|
55
|
+
export function buildUfgLaunchTransactions(options) {
|
|
56
|
+
const { plan, config } = options;
|
|
57
|
+
const principal = ufgPlanPrincipal(plan);
|
|
58
|
+
encodeUfgLaunchConfig(config);
|
|
59
|
+
return buildLaunchTransactions(options).map((transaction) => {
|
|
60
|
+
const data = transaction.kind === "atomic" ? encodeFunctionData({ abi: ufgLaunchProxyV1Abi, functionName: "launchAtomic", args: [plan, config] })
|
|
61
|
+
: transaction.kind === "begin" ? encodeFunctionData({ abi: ufgLaunchProxyV1Abi, functionName: "beginLaunch", args: [plan, LifecycleMode.Staged, config] }) : transaction.data;
|
|
62
|
+
return { ...transaction, from: principal, to: UFG_LAUNCH_PROXY_ADDRESS, data, calldataBytes: (data.length - 2) / 2 };
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
export function buildUfgCancelTransaction({ plan, preparedMarkets = 0 }) {
|
|
66
|
+
const data = encodeFunctionData({ abi: ufgLaunchProxyV1Abi, functionName: "cancelLaunch", args: [plan] });
|
|
67
|
+
return { id: "cancel", kind: "cancel", chainId: Number(plan.chainId), from: ufgPlanPrincipal(plan), to: UFG_LAUNCH_PROXY_ADDRESS, data, calldataBytes: (data.length - 2) / 2, value: 0n, dependencies: [], postconditions: [{ kind: "launch", phase: "Cancelled", preparedMarkets }] };
|
|
68
|
+
}
|
|
69
|
+
/** Exact summed proxy pulls, not escrow allowances. Current allowance/reset discovery belongs to planning. */
|
|
70
|
+
export function buildUfgApprovals(plan) {
|
|
71
|
+
const principal = ufgPlanPrincipal(plan);
|
|
72
|
+
const totals = new Map();
|
|
73
|
+
for (const funding of plan.funding) {
|
|
74
|
+
if (funding.kind === LifecycleFundingKind.NativeWrap || BigInt(funding.inputAsset) === 0n)
|
|
75
|
+
continue;
|
|
76
|
+
const asset = funding.kind === LifecycleFundingKind.ERC20 ? funding.asset : funding.inputAsset;
|
|
77
|
+
const amount = funding.kind === LifecycleFundingKind.ERC20 ? funding.amount : funding.inputAmount;
|
|
78
|
+
const key = asset.toLowerCase();
|
|
79
|
+
const entry = totals.get(key);
|
|
80
|
+
if (entry === undefined)
|
|
81
|
+
totals.set(key, { asset, amount });
|
|
82
|
+
else
|
|
83
|
+
entry.amount += amount;
|
|
84
|
+
}
|
|
85
|
+
const transactions = [...totals.values()].map(({ asset, amount }) => {
|
|
86
|
+
const data = encodeFunctionData({ abi: lifecycleErc20Abi, functionName: "approve", args: [UFG_LAUNCH_PROXY_ADDRESS, amount] });
|
|
87
|
+
return { id: `approve:${asset}`, kind: "approve", chainId: Number(plan.chainId), from: principal, to: asset, data, calldataBytes: (data.length - 2) / 2, value: 0n, dependencies: [], postconditions: [{ kind: "allowance", asset, spender: UFG_LAUNCH_PROXY_ADDRESS, minimum: amount }] };
|
|
88
|
+
});
|
|
89
|
+
return transactions.map((transaction, index) => ({ ...transaction, dependencies: index === 0 ? [] : [transactions[index - 1].id] }));
|
|
90
|
+
}
|
|
91
|
+
/** Read-only upstream treasury lookup. No treasury is represented by undefined, not the zero address. */
|
|
92
|
+
export async function readUfgTreasury(client, token) {
|
|
93
|
+
const data = encodeFunctionData({ abi: ufgTreasuryFactoryV1Abi, functionName: "treasuryOf", args: [token] });
|
|
94
|
+
const result = await client.request({ method: "eth_call", params: [{ to: UFG_TREASURY_FACTORY_ADDRESS, data }, "latest"] });
|
|
95
|
+
const treasury = decodeFunctionResult({ abi: ufgTreasuryFactoryV1Abi, functionName: "treasuryOf", data: result });
|
|
96
|
+
return treasury === zeroAddress ? undefined : treasury;
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=ufg.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ufg.js","sourceRoot":"","sources":["../../src/lifecycle/ufg.ts"],"names":[],"mappings":"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"}
|
package/docs/launch-lifecycle.md
CHANGED
|
@@ -7,6 +7,188 @@ The canonical authorities are the registry/certification/adapter/config contract
|
|
|
7
7
|
in the protocol repository. Plan identity is `LaunchPlanV1`. Pool-bound V4 uses **config 6**,
|
|
8
8
|
canonical Abyss uses **config 1**, and generic current shared-V4 support uses **config 4**.
|
|
9
9
|
|
|
10
|
+
## 0.12.0 release: opt-in UFG treasuries
|
|
11
|
+
|
|
12
|
+
UFG is an additive **proxy launch route**, not a new token kind or a replacement
|
|
13
|
+
for the core path. Existing launch defaults, calldata, salts and HMM behavior are
|
|
14
|
+
unchanged when `ufg` is omitted. The pinned Robinhood deployment (chain **4663**) is:
|
|
15
|
+
|
|
16
|
+
| Export | Address |
|
|
17
|
+
| --- | --- |
|
|
18
|
+
| `UFG_LAUNCH_PROXY_ADDRESS` | `0xf6673d859DE03eB74A0b01696Edb97f941dFD0CA` |
|
|
19
|
+
| `UFG_TREASURY_FACTORY_ADDRESS` | `0x26Aa5D52134c8E6c4C01E9fb53A7568c0C64901F` |
|
|
20
|
+
| `UFG_UPSTREAM_FACTORY_ADDRESS` | `0xA170b5A58C111334A7237F2Ea2c428ec5022f68E` |
|
|
21
|
+
| `UFG_ORCHESTRATOR_ADDRESS` | `0x91560876033d568d25CDe98C78c33ff8FC43962c` |
|
|
22
|
+
|
|
23
|
+
`KnownLifecycleProfile.V4UfgFixedPool` (`v4-ufg-fixed-pool`) selects profile
|
|
24
|
+
`0x5c6045af480814e469f3dba7c120d264047c9320b869c63a064536041a2dbae6`;
|
|
25
|
+
`V4UfgDynamicPool` (`v4-ufg-dynamic-pool`) selects
|
|
26
|
+
`0x03de8d5e38f2957d80ecb9f2e59d555601ff091dfb17bce84178956a2e8d9b41`.
|
|
27
|
+
`isUfgProfile` recognizes only these IDs. Frozen envelopes, adapter/registration/
|
|
28
|
+
topology and bound-hook metadata come from committed registry readback at block
|
|
29
|
+
**94,551,140** (`test/fixtures/ufg-registry-readback.json`). Regenerate with
|
|
30
|
+
`node --experimental-transform-types scripts/generate-ufg-presets.mjs /path/to/black-market`;
|
|
31
|
+
add `--readback` only to recapture that exact block with read-only RPC.
|
|
32
|
+
The fixed and zero-royalty dynamic creation bytes exactly match the existing
|
|
33
|
+
`FixedFeePoolV1` / `DynamicFeePoolV1` artifacts, so no duplicate hook enum is needed.
|
|
34
|
+
UFG deployers, lockers, collectors and adapters are nevertheless different graphs.
|
|
35
|
+
Frozen presets are construction evidence, not live admission.
|
|
36
|
+
|
|
37
|
+
### Configuration and supported markets
|
|
38
|
+
|
|
39
|
+
`UfgLaunchConfig` is `{ treasuryShareBps, exitFeeBps, reserveAssets }`. The proxy
|
|
40
|
+
requires treasury share **10000**, integer exit fee **0..2000 bps**, and **1..7**
|
|
41
|
+
nonzero, unique, strictly ascending reserve addresses, excluding the predicted
|
|
42
|
+
launch token. Reserves and market quotes must form exactly the same set.
|
|
43
|
+
|
|
44
|
+
- ERC20 only, no staking/dividends, zero executor fee and at least one market.
|
|
45
|
+
Neither inventory nor initial-buy recipients may be the proxy.
|
|
46
|
+
- Native Abyss uses the canonical adapter with config1 profile **2 (QUOTE)** or
|
|
47
|
+
**3 (QUOTE_ORACLE)** and the matching canonical profile ID. Its canonical
|
|
48
|
+
config has **no tail**.
|
|
49
|
+
- V4 uses config6 and one of the two UFG profiles, `feeMode: 1` (QuoteOnly) and
|
|
50
|
+
`lpFeePips: 0`. Preset zero-royalty terms still apply. Supply/position budgets,
|
|
51
|
+
price/ranges, oracle registration and ordinary lifecycle bounds are unchanged.
|
|
52
|
+
- Fee policies contain exactly the token plus reserves in ascending order:
|
|
53
|
+
token `{ ownerBps: 0, rewardsBps: 0, burnBps: 10000 }`, reserves
|
|
54
|
+
`{ ownerBps: 10000, rewardsBps: 0, burnBps: 0 }`.
|
|
55
|
+
`buildUfgFeeAssetPolicies(predictedToken, reserveAssets)` builds that exact set;
|
|
56
|
+
reserve ordering is validated, never silently repaired.
|
|
57
|
+
|
|
58
|
+
`encodeUfgLaunchConfig` encodes **one dynamic tuple**:
|
|
59
|
+
`abi.encode((uint16,uint16,address[]))`, including the leading `0x20` offset.
|
|
60
|
+
`decodeUfgLaunchConfig` checks canonical re-encoding; trailing bytes, alternate
|
|
61
|
+
offsets and dirty padding are rejected. `hashUfgLaunchConfig` is its keccak256.
|
|
62
|
+
Config6's typed `ufgLaunchConfig` automatically appends that encoding after the
|
|
63
|
+
canonical V6 prefix and decodes/splits it on read. Every UFG V4 tail must equal
|
|
64
|
+
the proxy config. The constructor economics hash remains **prefix-only with zero
|
|
65
|
+
hook salt**; the full plan hash binds the tail. No UFG tail is added to ordinary
|
|
66
|
+
V4, HMM or Abyss configs. Independent `cast abi-encode` fixtures are regenerated
|
|
67
|
+
with `node scripts/generate-ufg-fixtures.mjs`.
|
|
68
|
+
|
|
69
|
+
### Principal funding, planning and recovery
|
|
70
|
+
|
|
71
|
+
The economic plan's **creator is the proxy**. Its nonce is
|
|
72
|
+
`ufgLaunchNonce(principal, nonce96) = (uint160(principal) << 96) | nonce96`.
|
|
73
|
+
The `account` and every sender are the **same principal**, never the proxy.
|
|
74
|
+
The core still derives launch ID/token from the committed core/proxy/nonce.
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
const config = {
|
|
78
|
+
treasuryShareBps: 10000, exitFeeBps: 100,
|
|
79
|
+
reserveAssets: [getAddresses(4663).weth],
|
|
80
|
+
};
|
|
81
|
+
// economicPlan already contains your full token/funding/market/buy economics;
|
|
82
|
+
// every UFG V4 market was encoded with this same ufgLaunchConfig.
|
|
83
|
+
const plan = { ...economicPlan, creator: UFG_LAUNCH_PROXY_ADDRESS,
|
|
84
|
+
nonce: ufgLaunchNonce(principal, 1n) };
|
|
85
|
+
const token = await client.readContract({ address: plan.orchestrator,
|
|
86
|
+
abi: launchLifecycleAbi, functionName: "predictToken", args: [plan] });
|
|
87
|
+
plan.feeAssets = buildUfgFeeAssetPolicies(token, config.reserveAssets);
|
|
88
|
+
validateUfgLaunchPlan(plan, config, token); // pure/offline proxy rules
|
|
89
|
+
const planned = await prepareAndPlanLifecycleLaunch({
|
|
90
|
+
client, account: principal, plan, mode: "staged", ufg: { config },
|
|
91
|
+
});
|
|
92
|
+
// No signing here. Obtain fresh admitted proxy envelopes before wallet execution:
|
|
93
|
+
const next = await buildNextTransaction({ client, planned });
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
The opt-in works on `planLaunch` too. `PlannedLaunch.ufg` retains config and its
|
|
97
|
+
hash; `simulateLaunchPlan`, `readLaunchProgress`, and `buildNextTransaction`
|
|
98
|
+
(including `action: "cancel"`) retain the route and reject config mutation,
|
|
99
|
+
wrong principal/nonce, wrong receipt target/config, or proxy binding mismatch.
|
|
100
|
+
Salt mining and optional buy-minimum calibration use the existing machinery.
|
|
101
|
+
Native Nitro metering/execution proofs remain mandatory on production chain4663.
|
|
102
|
+
|
|
103
|
+
The proxy pulls summed non-native inputs from the principal: ERC20 asset/amount
|
|
104
|
+
or swap inputAsset/inputAmount. **Approve the proxy, not the funding escrow**.
|
|
105
|
+
`buildUfgApprovals(plan)` builds exact summed approvals; planning observes current
|
|
106
|
+
allowances and includes zero-reset commands when needed. Native-wrap and native
|
|
107
|
+
swap inputs are `msg.value` on atomic/begin only. Refunds return to the principal.
|
|
108
|
+
|
|
109
|
+
Pure `buildUfgLaunchTransactions({ plan, config, mode, preparationBatches })`
|
|
110
|
+
produces proxy `launchAtomic(plan, config)`, or `beginLaunch(plan, Staged, config)`,
|
|
111
|
+
ordered `prepareMarkets` batches, then `activateLaunch`. The explicit batches
|
|
112
|
+
must cover all markets. `buildUfgCancelTransaction({ plan, preparedMarkets })`
|
|
113
|
+
targets the same proxy. These builders alone do not establish execution admission.
|
|
114
|
+
`validateUfgLaunchPlan` checks offline proxy rules; live registry continuity,
|
|
115
|
+
reserve/token code and supply bounds, transfers and treasury creation require RPC
|
|
116
|
+
simulation. The existing non-UFG core transaction builder is intentionally unchanged.
|
|
117
|
+
|
|
118
|
+
`readUfgTreasury(client, token)` reads the treasury factory's `treasuryOf(token)`
|
|
119
|
+
and returns the upstream address, or `undefined` for zero. Complete
|
|
120
|
+
`ufgLaunchProxyV1Abi`, `ufgTreasuryFactoryV1Abi`, `ufgBlackMarketFactoryAbi` and
|
|
121
|
+
`ufgBlackMarketTreasuryAbi` expose proxy config hashes and upstream treasury
|
|
122
|
+
collect/redeem/assets/backing/position/debt operations without inventing wrappers.
|
|
123
|
+
The pure example is `node examples/ufg-launch-config.ts` after building.
|
|
124
|
+
|
|
125
|
+
### UFG owned-fork check
|
|
126
|
+
|
|
127
|
+
This explicitly authorized local-only integration uses the unlocked Anvil default
|
|
128
|
+
account, no keys, and only public SDK launch APIs. In separate terminals:
|
|
129
|
+
|
|
130
|
+
```sh
|
|
131
|
+
anvil --fork-url https://rpc.mainnet.chain.robinhood.com/ \
|
|
132
|
+
--chain-id 4663 --port 8561 \
|
|
133
|
+
--gas-limit 100000000 --silent
|
|
134
|
+
pnpm build
|
|
135
|
+
UFG_FORK_RPC_URL=http://127.0.0.1:8561 node test/integration/ufg-launch.fork.mjs
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
It validates the tuple against the deployed factory, mines bound-hook salts,
|
|
139
|
+
executes Abyss QUOTE atomic, mixed Abyss QUOTE + UFG fixed staged (ERC20 funding/
|
|
140
|
+
proxy approval), and UFG dynamic atomic launches. It calls each exact proxy
|
|
141
|
+
command from the principal first, then checks Active, a nonzero `readUfgTreasury`
|
|
142
|
+
and `proxy.launchConfigHash == hashUfgLaunchConfig`. Snapshot restoration makes
|
|
143
|
+
the check repeatable. Stop Anvil afterward. Generic Anvil proves EVM contract
|
|
144
|
+
behavior here, **not ArbOS compute/poster admission**: construction/read/mining/
|
|
145
|
+
unsigned APIs plus actual fork `eth_call`/receipts are used, not a fake native
|
|
146
|
+
Nitro planner certificate. Ordinary `pnpm test` never runs this funded check.
|
|
147
|
+
|
|
148
|
+
## 0.11.0 release: gas sizing, packing and prefix proof
|
|
149
|
+
|
|
150
|
+
New atomic/activation envelopes containing HMM V2 markets add one forwarding target:
|
|
151
|
+
`R = 4_250_000 + 500_000 * (hmmMarkets - 1)` gas (zero for non-HMM plans).
|
|
152
|
+
For measured gross gas `G` (`maxUsedGas`, falling back to `gasUsed`), compute is
|
|
153
|
+
`min(max(G + R, ceil(G * (10000 + headroomBps) / 10000)), computeCap)`.
|
|
154
|
+
Begin/preparation/approval/cancel commands do not receive this reserve. Nitro poster
|
|
155
|
+
gas is budgeted separately inside the same complete gas envelope. Optional padding
|
|
156
|
+
and the reserve are targets, not refusal thresholds; exact validated replay proves
|
|
157
|
+
the clamped envelope. There is no bisection or extra ordinary-path request.
|
|
158
|
+
|
|
159
|
+
Staged planning greedily packs contiguous markets against the unpadded compute cap:
|
|
160
|
+
HMM V2 costs 14.5M per market; other profiles cost a conservative 16M. At 32M,
|
|
161
|
+
1/2/3/5 HMM markets produce `[1]`/`[2]`/`[2,1]`/`[2,2,1]`.
|
|
162
|
+
Only a packed measurement failure consuming at least 95% of its given gas splits
|
|
163
|
+
that batch in half, regardless of its error selector. Low-gas semantic failures
|
|
164
|
+
remain failures. `preparationBatchSize` is removed; inspect each preparation's
|
|
165
|
+
`marketStart`/`marketCount`. The pure unsigned compiler still accepts explicit
|
|
166
|
+
`preparationBatches`.
|
|
167
|
+
|
|
168
|
+
Robinhood chain 4663 defaults `limits.maxSimulationGas` to **50_000_000n** aggregate
|
|
169
|
+
gas **used**, not the sum of individual legal transaction envelopes. Override it
|
|
170
|
+
for a provider with a different budget. The SDK measures and validates the longest
|
|
171
|
+
estimated prefix that fits: begin 9.5M, preparations as above, activation 6M per
|
|
172
|
+
market plus `R`, and small approvals/cancellation. A measurement failure after
|
|
173
|
+
cumulative use reaches 95% of that cap defers the failed call and suffix.
|
|
174
|
+
If even the immediate estimate cannot fit that budget, refusal first identifies
|
|
175
|
+
any estimated per-transaction compute overflow (gas displayed in millions to one
|
|
176
|
+
decimal), rather than suggesting that a larger RPC budget solves it. Estimates
|
|
177
|
+
alone do not reject an envelope that can still be measured and exactly proved.
|
|
178
|
+
|
|
179
|
+
`simulation.admitted`, `executionProof: "proved"` and `protocolFit: "proved"` cover
|
|
180
|
+
only the successful proven prefix. **They do not promise eventual activation.**
|
|
181
|
+
`simulation.deferredTransactionIds` explicitly lists unproved remaining steps
|
|
182
|
+
(empty for full coverage); these commands carry no `gas`, `gasPrice`, `estimate`
|
|
183
|
+
or `admission`. Call `buildNextTransaction` before each signature: canonical
|
|
184
|
+
progress advances the proof window and gives the immediate next transaction exact
|
|
185
|
+
gas. Reviewed envelopes receive only a direct exact replay of that immediate step,
|
|
186
|
+
without new measurement, poster/price recommendations or suffix proof.
|
|
187
|
+
|
|
188
|
+
`buySlippageBps` requires actual activation outputs. If activation is deferred,
|
|
189
|
+
calibration refuses clearly; use a higher-budget native provider or preserve
|
|
190
|
+
already committed minima by omitting recalibration. Outputs are never fabricated.
|
|
191
|
+
|
|
10
192
|
## 0.9.1 release: Abyss 0.01% fee tier
|
|
11
193
|
|
|
12
194
|
`ABYSS_FEE_TIERS` now includes `{ feePips: 100, tickSpacing: 1, label: "0.01%" }`.
|
|
@@ -342,15 +524,13 @@ progress, funding/allowances and deployment/profile authority. It matches
|
|
|
342
524
|
Preparation batching remains SDK-derived, not caller-selected. Malformed,
|
|
343
525
|
wrong-step or changed envelopes refuse without returning executable calldata.
|
|
344
526
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
an invalid current fee, insufficient gas or failed proof never silently raises
|
|
353
|
-
the held envelope.
|
|
527
|
+
The SDK directly validates only the immediate transaction at its exact held
|
|
528
|
+
gas/price. It does not repeat measurement, quote a new gas price/poster budget or
|
|
529
|
+
simulate future steps. Current protocol/transaction limits, native metering,
|
|
530
|
+
postconditions and immediate actual-balance affordability still apply. Existing
|
|
531
|
+
padding may be consumed; neither a new padding target nor a higher advisory quote
|
|
532
|
+
alone invalidates a held envelope. Natural child base fees and payer balances are
|
|
533
|
+
never overridden, and failed replay never raises held gas or switches backend.
|
|
354
534
|
|
|
355
535
|
Approvals/resets, atomic launches, every staged next step and cancellation use
|
|
356
536
|
this same contract. Cancellation retains its adapter-independent recovery policy.
|
|
@@ -742,13 +922,13 @@ Validation uses `validateV4LifecycleMarket`; the collector factory getter is
|
|
|
742
922
|
| --- | --- |
|
|
743
923
|
| `readLifecycleProfiles({client, orchestrator, profileIds?, offset?, limit?})` | Bounded registry discovery, schema/topology dispatch, reviewed graph/terms certification and current registry admission. Default offset/limit is 0/100; explicit IDs can select a reviewed deployment's identities. |
|
|
744
924
|
| `predictLifecycleToken({client, plan})` | Exact prediction from the explicit core. |
|
|
745
|
-
| `prepareAndPlanLifecycleLaunch({client, account, plan, mode, allowTopologyGaps?, allowMissingPermanentTail?, limits?, fork?, receipts?, confirmations?, signal?, onProgress?})` | Mines config6/V2 salts offchain, verifies per-market
|
|
925
|
+
| `prepareAndPlanLifecycleLaunch({client, account, plan, mode, buySlippageBps?, allowTopologyGaps?, allowMissingPermanentTail?, limits?, fork?, receipts?, confirmations?, signal?, onProgress?})` | Mines config6/V2 salts offchain, verifies per-market topology and exact final deployment bindings, and proves the selected-mode prefix under one fresh post-mining snapshot. Reports deferred steps; buy calibration requires activation coverage. No source-chain deployment or broadcast. |
|
|
746
926
|
| `readPoolBoundHookDeployment({client, plan, marketIndex})` | Verifies typed factory, code chunks, constructor, normalized economics, initcode, salt, CREATE2 prediction and recorded provenance of existing code. Works with draft salts; permission bits are additionally required for executable predeployment. |
|
|
747
927
|
| `buildPoolBoundHookDeploymentTransaction({client, plan, marketIndex})` | Optional permissionless typed `deploy(parameters,salt)` calldata. Does not create a token, register/initialize a pool, bind a collector or activate a launch. |
|
|
748
928
|
| `planLaunch({client, account, plan, mode, allowTopologyGaps?, allowMissingPermanentTail?, limits?, fork?, receipts?, confirmations?, signal?})` | Independently fresh per-market topology/domain/funding/profile/progress/execution admission of the already-finalized commitment, simulating only the explicitly selected mode. |
|
|
749
929
|
| `simulateLaunchPlan({client, planned, limits?, fork?, receipts?, confirmations?})` | Rereads canonical state and proves remaining work. Preserves receipt evidence, economics and selected mode. |
|
|
750
930
|
| `readLaunchProgress({client, planned, receipts?, confirmations?})` | Confirmation-bound canonical state, latest head, receipt/replacement/reorg status, account-nonce safety and actual prepared market/live state. |
|
|
751
|
-
| `buildNextTransaction({client, planned, reviewedTransaction?, submissionClient?, limits?, fork?, receipts?, confirmations?, action?})` | Rereads progress
|
|
931
|
+
| `buildNextTransaction({client, planned, reviewedTransaction?, submissionClient?, limits?, fork?, receipts?, confirmations?, action?})` | Rereads canonical progress and constraints, proves the immediate next transaction plus the fitting prefix, and returns one admitted envelope. With `reviewedTransaction`, directly replays only that matching immediate step at its exact held gas/price. Optional `submissionClient` adds read-only exact-envelope preflight. `action: "cancel"` retains adapter-independent recovery. Terminal launches return `undefined`. |
|
|
752
932
|
|
|
753
933
|
Clients may be viem public clients or raw `request({method,params})` RPC clients. Transport, wallet, signing and durable storage are application-owned. `PlannedLaunch` contains bigint values and live limit callbacks: persist `serializeLaunchPlan(plan)`, explicit execution mode, confirmation policy and receipt references, not the entire object.
|
|
754
934
|
|
|
@@ -879,17 +1059,17 @@ Mining is cancellable/nonblocking; `abort()` raises `AbortError` and does not ca
|
|
|
879
1059
|
Every planning call requires `mode: "atomic" | "staged"`. Only that requested mode receives economic simulation; staged does not compute or expose an unused atomic attempt.
|
|
880
1060
|
|
|
881
1061
|
- Atomic: after funding prerequisites, token creation, empty infrastructure, all mint/lock/buys/public activation are one transaction.
|
|
882
|
-
- Staged: prerequisites, `beginLaunch(Staged)`, contiguous empty `prepareMarkets` batches, then one `activateLaunch`.
|
|
1062
|
+
- Staged: prerequisites, `beginLaunch(Staged)`, greedily packed contiguous empty `prepareMarkets` batches, then one `activateLaunch`. A packed measurement failure using at least 95% of its given gas splits only that batch; low-gas semantic errors, byte caps and unlocated provider failures do not justify a split. Proof may cover only a prefix, with the unproved suffix explicitly deferred.
|
|
883
1063
|
- Activation cannot split. If mint/lock/all buys/opening cannot fit, staged is also refused. No position/buy/minimum is omitted to manufacture success.
|
|
884
1064
|
|
|
885
1065
|
No automatic atomic-to-staged fallback exists. Obtain separate consent to review the same commitment as staged. Both venues use token transfer restrictions plus activation-time canonical opening-state checks, not a pool gate. Manipulated opening price or preactivation liquidity fails verification; the token stays inactive and the launch remains Ready/cancellable. Failed activation rolls back every mint, seal, buy and opening together.
|
|
886
1066
|
|
|
887
1067
|
## Execution constraints and stateful simulation
|
|
888
1068
|
|
|
889
|
-
Optional `chainGasLimit`, `rpcGasLimit`, `accountGasLimit
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
1069
|
+
Optional `chainGasLimit`, `rpcGasLimit`, `accountGasLimit` and `maxCalldataBytes`
|
|
1070
|
+
tighten admission. `maxSimulationGas` sets the aggregate used-gas proof-window
|
|
1071
|
+
budget (default 50M on 4663, unknown on other chains). Missing policy stays explicit
|
|
1072
|
+
in `limits.unknownExecutionConstraints`/`unknownConstraints`; no policy service is required.
|
|
893
1073
|
A `LifecycleLimitSource` callback receives the canonical chain/account/core/block context.
|
|
894
1074
|
Any supplied provenance must match it; stale/mismatched/malformed facts or a failed supplied
|
|
895
1075
|
resolver reject rather than disappearing into optional uncertainty. Gas caps are positive
|
|
@@ -897,7 +1077,9 @@ exact uint64 `bigint`; calldata is a positive safe integer byte count.
|
|
|
897
1077
|
Reviewed gas envelopes are positive uint64 too; zero-metering observations cannot admit
|
|
898
1078
|
a zero-gas transaction. Headroom calculations retain wide exact bigint intermediates.
|
|
899
1079
|
|
|
900
|
-
Headroom defaults to 1,500 bps, bounded 0–10,000
|
|
1080
|
+
Headroom defaults to 1,500 bps, bounded 0–10,000; it clamps to current legal ceilings
|
|
1081
|
+
instead of rejecting a fitting measured requirement. HMM V2 adds the forwarding
|
|
1082
|
+
target documented above once on atomic/activation. Generic EVM admission uses the pinned
|
|
901
1083
|
bounded header and supplied total-envelope restrictions plus actual validated RPC proof.
|
|
902
1084
|
It reports an absent independent per-transaction cutoff honestly, without importing a
|
|
903
1085
|
universal Ethereum cutoff. `executionGasCeiling` and `transactionGasCeiling` are equal on
|
|
@@ -910,8 +1092,8 @@ carries that successfully replayed ceiling, never a smaller unproved envelope.
|
|
|
910
1092
|
Replay source, HTTP and malformed-response failures remain provisional with
|
|
911
1093
|
`executionProof: "unavailable"` and do not retry economic execution. `AbortError`
|
|
912
1094
|
propagates unchanged, including cancellation during supplied policy and Nitro getter
|
|
913
|
-
reads.
|
|
914
|
-
validated envelope within the same legal compute/total limits. Without returned
|
|
1095
|
+
reads. Only explicit genuine native out-of-gas evidence may discover at most one
|
|
1096
|
+
larger validated envelope within the same legal compute/total limits. Without returned
|
|
915
1097
|
failing-call evidence, `failedTransactionId` stays absent; an opaque RPC error does
|
|
916
1098
|
not invent a failing transaction or authorize preparation partitioning.
|
|
917
1099
|
Returned failures retain the actual exact-replay prefix and its first failing
|
|
@@ -949,10 +1131,10 @@ The buffered compute-discovery envelope plus buffered poster budget is carried i
|
|
|
949
1131
|
exact validated replay; an approximate poster quote is never subtracted from total
|
|
950
1132
|
gas use to certify exact compute fit.
|
|
951
1133
|
Measurement waits for successful capability and candidate-specific poster evidence,
|
|
952
|
-
then uses the legal complete compute-plus-poster envelope.
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
can
|
|
1134
|
+
then uses the legal complete compute-plus-poster envelope. A packed preparation
|
|
1135
|
+
failure consuming at least 95% may invalidate its cost estimate without claiming
|
|
1136
|
+
its selector diagnoses OOG. Unsupported/transport evidence remains unavailable,
|
|
1137
|
+
except an observed aggregate-budget exhaustion can preserve a successful prefix.
|
|
956
1138
|
|
|
957
1139
|
A separate pinned validated simulation probes all three ArbOS/version/getter values
|
|
958
1140
|
against the canonical observations. Only that isolated capability probe temporarily
|
|
@@ -975,13 +1157,13 @@ does not manufacture an all-in estimate. All observations and limits refresh for
|
|
|
975
1157
|
For initial construction, the exact legacy gas-price envelope is the greater of
|
|
976
1158
|
the fresh RPC recommendation and twice the pinned base fee. This avoids
|
|
977
1159
|
underpriced submission when `eth_gasPrice` lags the block base fee. Reviewed
|
|
978
|
-
envelopes retain
|
|
979
|
-
|
|
1160
|
+
envelopes retain exact gas/price through direct immediate native validated replay
|
|
1161
|
+
and immediate affordability, without repeating measurement or applying new padding.
|
|
980
1162
|
The held price need not equal a new recommendation or twice the current base fee;
|
|
981
1163
|
natural child fees and the actual submission estimate must accept it. Replay,
|
|
982
1164
|
affordability and submission use that same price, without a base-fee override.
|
|
983
|
-
|
|
984
|
-
|
|
1165
|
+
An aggregate budget selects the longest fitting estimated prefix; only when even
|
|
1166
|
+
the immediate estimate does not fit is no proof possible. A definitive returned
|
|
985
1167
|
failure from the final exact replay skips a later payer-balance lookup, while
|
|
986
1168
|
retaining fee/estimate validation and final canonical checks. Successful replay
|
|
987
1169
|
still requires current actual-balance affordability.
|
|
@@ -1013,14 +1195,15 @@ Simulation and `next.admission` carry flat, independent proof outcomes:
|
|
|
1013
1195
|
|
|
1014
1196
|
| Field | Values | Scope |
|
|
1015
1197
|
| --- | --- | --- |
|
|
1016
|
-
| `executionProof` | `"proved"`, `"failed"`, `"unavailable"` |
|
|
1198
|
+
| `executionProof` | `"proved"`, `"failed"`, `"unavailable"` | Stateful exact-envelope execution/postconditions for the proven prefix (or the immediate reviewed step), never measurement alone or an unproved suffix. |
|
|
1017
1199
|
| `protocolFit` | `"proved"`, `"failed"`, `"unknown"` | Applicable proven protocol and known tightening restrictions. Missing optional policy remains separately disclosed. |
|
|
1018
1200
|
| `transportPreflight` | `"not-requested"`, `"passed"`, `"failed"` | Immediate exact next-transaction acceptance estimate on the supplied submission RPC. |
|
|
1019
1201
|
|
|
1020
|
-
`admitted` means the
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1202
|
+
`admitted` means the proven prefix fits and is affordable, not that deferred
|
|
1203
|
+
transactions have executed or that eventual activation is guaranteed. Always
|
|
1204
|
+
inspect `simulation.deferredTransactionIds`. Admission reuses `blockNumber`,
|
|
1205
|
+
`blockHash`, `account`, `chainId` and `limits`; signing uses only fresh build-next
|
|
1206
|
+
admission. Plans never preflight future steps independently against nonexistent state.
|
|
1024
1207
|
|
|
1025
1208
|
```ts
|
|
1026
1209
|
const planned = await planLaunch({ client, account: plan.creator, plan, mode: "atomic" });
|
package/examples/.env.example
CHANGED
|
@@ -35,3 +35,7 @@ NFT_BASE_URI=
|
|
|
35
35
|
# EXAMPLE_ACCOUNT_GAS_CAP=
|
|
36
36
|
# EXAMPLE_MAX_CALLDATA_BYTES=
|
|
37
37
|
# EXAMPLE_HEADROOM_BPS=1500
|
|
38
|
+
#
|
|
39
|
+
# Robinhood aggregate simulation gas-used budget defaults to 50M. Override only for
|
|
40
|
+
# a provider supporting that budget; buy-output calibration needs activation coverage.
|
|
41
|
+
# EXAMPLE_SIMULATION_GAS_CAP=100000000
|
package/examples/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Examples
|
|
2
2
|
|
|
3
|
-
The launch examples use the public `@black-market/sdk` 0.
|
|
3
|
+
The launch examples use the public `@black-market/sdk` 0.12.0 package and viem.
|
|
4
4
|
Build this checkout before running its examples; in a consumer project install
|
|
5
|
-
`@black-market/sdk@0.
|
|
5
|
+
`@black-market/sdk@0.12.0` for opt-in UFG treasuries and current proof semantics.
|
|
6
6
|
The default chain-4663 launch cases retain
|
|
7
7
|
the October8 mined fixed pool-bound V4 config6/V2 and canonical Abyss config1 deployment.
|
|
8
8
|
The SDK additionally knows the October11 zero-author-royalty Dynamic Fee Hook;
|
|
@@ -25,11 +25,25 @@ examples; their relative support imports use explicit `.ts` extensions for Node
|
|
|
25
25
|
| --- | --- |
|
|
26
26
|
| `quickstart.ts` | Reads the current mainnet orchestrator, checks its registry binding, and discovers admitted profiles. No wallet or writes. |
|
|
27
27
|
| `hmm-launch-config.ts` | Pure HMM V2 fixed/dynamic config construction with caller-chosen bid/reference guards and an automatically appended 512-byte launch tail; no RPC, signatures or writes. |
|
|
28
|
+
| `ufg-launch-config.ts` | Pure fixed/dynamic UFG quote-only config6 construction, canonical reserve tail and config hash; no RPC, wallet or writes. |
|
|
28
29
|
| `launch.ts` | Reviews/reconstructs an explicit saved plan and selected atomic/staged mode; optional offchain config6/V2 salt mining. Prints simulation, progress, and an admitted unsigned next transaction when evidence permits. |
|
|
29
30
|
| `generate-lifecycle-commitment-fixture.ts` | Frozen independent historical config4/Abyss ABI bytes/hash/identity vector. Its pre-cutover allocations are not an executable 0.7.1 plan. |
|
|
30
31
|
| `launch-lifecycle-smoke.ts` | Actual SDK launch/recovery/custody/fee operations, only on an explicitly authorized owned disposable loopback graph. |
|
|
31
32
|
| `launch-erc20-*.ts`, `launch-erc404-*.ts` | Eleven independent fixed cases: unsigned end-to-end planning by default; `--broadcast` adds guarded local signing, chain verification and mandatory API publication/indexing. |
|
|
32
33
|
|
|
34
|
+
## UFG treasury configuration
|
|
35
|
+
|
|
36
|
+
Run `pnpm build && node examples/ufg-launch-config.ts` for a pure consumer example.
|
|
37
|
+
Real UFG plans use the proxy as creator and a principal-namespaced nonce, with
|
|
38
|
+
`ufg: { config }` on `prepareAndPlanLifecycleLaunch`; the principal remains the
|
|
39
|
+
planning/signing account. Use only reward-free ERC20, full treasury reserve share,
|
|
40
|
+
launch-token burn policies, Abyss QUOTE/QUOTE_ORACLE or the UFG fixed/dynamic
|
|
41
|
+
presets. Approvals go to the proxy. The existing eleven launch cases and their
|
|
42
|
+
selected non-UFG offerings are intentionally unchanged.
|
|
43
|
+
|
|
44
|
+
The opt-in owned-fork regression is `test/integration/ufg-launch.fork.mjs`; see the
|
|
45
|
+
[lifecycle guide](../docs/launch-lifecycle.md#ufg-owned-fork-check).
|
|
46
|
+
|
|
33
47
|
## Deployed read-only discovery
|
|
34
48
|
|
|
35
49
|
```sh
|
|
@@ -73,6 +87,18 @@ generic EVM, not as a Nitro metering substitute. Unsigned review reports
|
|
|
73
87
|
RPC to build-next. See the
|
|
74
88
|
[lifecycle guide](../docs/launch-lifecycle.md#execution-constraints-and-stateful-simulation).
|
|
75
89
|
|
|
90
|
+
Robinhood defaults to a 50M aggregate simulation gas-used budget. Inspect
|
|
91
|
+
`simulation.deferredTransactionIds`: admitted/proved means the proven prefix,
|
|
92
|
+
not every future transaction or eventual activation. Deferred commands have no
|
|
93
|
+
gas/price/estimate/admission; obtain each fresh immediate envelope through
|
|
94
|
+
`buildNextTransaction` after canonical progress advances. Reviewed envelopes are
|
|
95
|
+
replayed directly, without measuring/replaying the suffix again. The saved-plan
|
|
96
|
+
CLI prints proof coverage and never signs. Override `limits.maxSimulationGas` only
|
|
97
|
+
for a provider that supports the selected budget. Examples requiring actual
|
|
98
|
+
activation outputs for `buySlippageBps` or economic review refuse if activation is
|
|
99
|
+
deferred; use a suitably higher-budget provider rather than inventing buy outputs.
|
|
100
|
+
|
|
101
|
+
|
|
76
102
|
For a real new graph, create the saved plan using `readLifecycleProfiles` with its
|
|
77
103
|
explicit chain/core and admitted pool-bound config6 profile. Supply that graph's RPC
|
|
78
104
|
to `launch.ts`; do not substitute the historical known preset. Applications may use
|
|
@@ -381,6 +407,13 @@ to tighten the complete transaction envelope: `EXAMPLE_CHAIN_GAS_CAP`,
|
|
|
381
407
|
restrictions, not invented provider/account assurances or admission bypasses.
|
|
382
408
|
Poster allocation is already inside Nitro gas/affordability and is not charged twice.
|
|
383
409
|
|
|
410
|
+
Robinhood's separate aggregate simulation gas-used budget defaults to **50M**.
|
|
411
|
+
`EXAMPLE_SIMULATION_GAS_CAP` overrides that budget (positive decimal gas) for
|
|
412
|
+
providers supporting more or less. It does not change per-transaction compute
|
|
413
|
+
capacity. Multi-step examples requiring full activation outputs for buy protection
|
|
414
|
+
and economic review need a provider/budget covering activation, or refuse before
|
|
415
|
+
signing; do not raise the setting beyond the provider's actual supported budget.
|
|
416
|
+
|
|
384
417
|
### Evidence and failure recovery
|
|
385
418
|
|
|
386
419
|
Each dry run or broadcast automatically creates `launch-results/<timestamp-case-random>/`;
|
|
@@ -540,6 +540,7 @@ export async function readExampleConfiguration(sdk, redactor, env = process.env)
|
|
|
540
540
|
chainTransactionGasLimit: gasCap("EXAMPLE_CHAIN_GAS_CAP"),
|
|
541
541
|
rpcTransactionGasLimit: gasCap("EXAMPLE_RPC_GAS_CAP"),
|
|
542
542
|
accountTransactionGasLimit: gasCap("EXAMPLE_ACCOUNT_GAS_CAP"),
|
|
543
|
+
rpcTotalSimulationGasLimit: gasCap("EXAMPLE_SIMULATION_GAS_CAP"),
|
|
543
544
|
maxCalldataBytes: integer("EXAMPLE_MAX_CALLDATA_BYTES", undefined, 1, Number.MAX_SAFE_INTEGER),
|
|
544
545
|
headroomBps: integer("EXAMPLE_HEADROOM_BPS", 1500, 0, 10000),
|
|
545
546
|
provenance: { scope: "user-ceilings", note: "Optional local tightening restrictions, not verified provider or account limits" },
|
|
@@ -477,6 +477,7 @@ function limitSource(fixture, artifacts) {
|
|
|
477
477
|
chainGasLimit: policy.chainTransactionGasLimit === undefined ? undefined : BigInt(policy.chainTransactionGasLimit),
|
|
478
478
|
rpcGasLimit: policy.rpcTransactionGasLimit === undefined ? undefined : BigInt(policy.rpcTransactionGasLimit),
|
|
479
479
|
accountGasLimit: policy.accountTransactionGasLimit === undefined ? undefined : BigInt(policy.accountTransactionGasLimit),
|
|
480
|
+
maxSimulationGas: policy.rpcTotalSimulationGasLimit === undefined ? undefined : BigInt(policy.rpcTotalSimulationGasLimit),
|
|
480
481
|
maxCalldataBytes: policy.maxCalldataBytes, headroomBps: policy.headroomBps,
|
|
481
482
|
};
|
|
482
483
|
artifacts.event("execution-limits", { limits, provenance: policy.provenance });
|
package/examples/launch.ts
CHANGED
|
@@ -30,6 +30,7 @@ const options = { client, account: plan.creator, plan, mode, limits, fork, recei
|
|
|
30
30
|
const planned = args.includes("--mine")
|
|
31
31
|
? await prepareAndPlanLifecycleLaunch({ ...options, onProgress: ({ marketIndex, attempts }) => console.error("salt mining", marketIndex, attempts.toString()) })
|
|
32
32
|
: await planLaunch(options);
|
|
33
|
+
console.error("Proof coverage:", planned.simulation.steps.length, "steps; deferred:", planned.simulation.deferredTransactionIds);
|
|
33
34
|
const progress = await readLaunchProgress({ client, planned, receipts, confirmations });
|
|
34
35
|
const next = planned.simulation.admitted ? await buildNextTransaction({ client, planned, limits, fork, receipts, confirmations }) : undefined;
|
|
35
36
|
console.log(JSON.stringify({ plan: JSON.parse(serializeLaunchPlan(planned.plan)), mode,
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// Pure configuration example; no RPC, wallet, key, signing or broadcast.
|
|
2
|
+
// This is not a priced/admitted plan. Use core.predictToken(plan) for real fee policies,
|
|
3
|
+
// derive funded one-sided positions, then prepareAndPlanLifecycleLaunch({ ..., ufg: { config } }).
|
|
4
|
+
import { encodeAbiParameters, keccak256, zeroHash } from "viem";
|
|
5
|
+
import {
|
|
6
|
+
getAddresses, KnownLifecycleProfile, getKnownLifecycleProfile,
|
|
7
|
+
UFG_ORCHESTRATOR_ADDRESS, UFG_LAUNCH_PROXY_ADDRESS, encodeUfgLaunchConfig,
|
|
8
|
+
hashUfgLaunchConfig, encodePoolBoundV4LifecycleMarketConfig,
|
|
9
|
+
} from "@black-market/sdk";
|
|
10
|
+
|
|
11
|
+
const identity = { chainId: 4663n, orchestrator: UFG_ORCHESTRATOR_ADDRESS };
|
|
12
|
+
const config = { treasuryShareBps: 10000, exitFeeBps: 100, reserveAssets: [getAddresses(4663).weth] };
|
|
13
|
+
for (const key of [KnownLifecycleProfile.V4UfgFixedPool, KnownLifecycleProfile.V4UfgDynamicPool]) {
|
|
14
|
+
const preset = getKnownLifecycleProfile({ ...identity, key })!;
|
|
15
|
+
const envelope = preset.profile.envelope!;
|
|
16
|
+
const encoded = encodePoolBoundV4LifecycleMarketConfig({
|
|
17
|
+
version: 6, lpFeePips: 0, tickSpacing: 60, sqrtPriceX96: 1n << 96n,
|
|
18
|
+
hookFeePips: 10000, minimumHookFeePips: 1000, feeSensitivityPipsSecondsPerTick: 7654321,
|
|
19
|
+
feeMode: 1, protocolFeeDenominator: envelope.protocolFeeDenominator,
|
|
20
|
+
treasury: envelope.protocolTreasury, externalLiquidityDisabled: false,
|
|
21
|
+
oracleConfigId: keccak256(encodeAbiParameters([{ type: "uint24" }, { type: "uint16" }], [1, 4096])),
|
|
22
|
+
hookSalt: zeroHash, profileId: preset.profile.id, termsDigest: envelope.termsDigest,
|
|
23
|
+
developerBeneficiary: envelope.beneficiary, developerFeeBps: 0,
|
|
24
|
+
// Geometry/price are illustrative. Real launch uses predicted token ordering and budget-funded ranges.
|
|
25
|
+
positions: [{ tickLower: 0, tickUpper: 887220, liquidity: 1000n, salt: zeroHash, maxTokenAmount: 1000000n }],
|
|
26
|
+
ufgLaunchConfig: config,
|
|
27
|
+
});
|
|
28
|
+
console.log(key, { proxy: UFG_LAUNCH_PROXY_ADDRESS, profileId: preset.profile.id,
|
|
29
|
+
configBytes: (encoded.length - 2) / 2, tailBytes: (encodeUfgLaunchConfig(config).length - 2) / 2,
|
|
30
|
+
launchConfigHash: hashUfgLaunchConfig(config) });
|
|
31
|
+
}
|
package/package.json
CHANGED
package/src/lifecycle/abi.ts
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
} from "./schema.js";
|
|
7
7
|
import { poolBoundHookParametersV1Components, poolBoundHookParametersV2Components, v4LifecycleMarketComponents } from "./markets.js";
|
|
8
8
|
export { hmmLiquidityManagerV2Abi, hmmFeeCollectorV2Abi, hmmFeeCollectorFactoryV2Abi, hmmFixedHookV2Abi, hmmDynamicHookV2Abi } from "./hmm-abi.js";
|
|
9
|
+
export { ufgLaunchProxyV1Abi, ufgTreasuryFactoryV1Abi, ufgBlackMarketFactoryAbi, ufgBlackMarketTreasuryAbi } from "./ufg-abi.js";
|
|
9
10
|
|
|
10
11
|
const planInput = { name: "plan", type: "tuple", components: launchPlanV1Components } as const;
|
|
11
12
|
export const launchLifecycleAbi = [
|