@black-market/sdk 0.11.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.
Files changed (66) hide show
  1. package/README.md +17 -0
  2. package/dist/lifecycle/abi.d.ts +1 -0
  3. package/dist/lifecycle/abi.d.ts.map +1 -1
  4. package/dist/lifecycle/abi.js +1 -0
  5. package/dist/lifecycle/abi.js.map +1 -1
  6. package/dist/lifecycle/deployments/ufg-dynamic-pool-20261021.d.ts +71 -0
  7. package/dist/lifecycle/deployments/ufg-dynamic-pool-20261021.d.ts.map +1 -0
  8. package/dist/lifecycle/deployments/ufg-dynamic-pool-20261021.js +73 -0
  9. package/dist/lifecycle/deployments/ufg-dynamic-pool-20261021.js.map +1 -0
  10. package/dist/lifecycle/deployments/ufg-fixed-pool-20261021.d.ts +71 -0
  11. package/dist/lifecycle/deployments/ufg-fixed-pool-20261021.d.ts.map +1 -0
  12. package/dist/lifecycle/deployments/ufg-fixed-pool-20261021.js +73 -0
  13. package/dist/lifecycle/deployments/ufg-fixed-pool-20261021.js.map +1 -0
  14. package/dist/lifecycle/index.d.ts +1 -0
  15. package/dist/lifecycle/index.d.ts.map +1 -1
  16. package/dist/lifecycle/index.js +1 -0
  17. package/dist/lifecycle/index.js.map +1 -1
  18. package/dist/lifecycle/markets.d.ts +3 -1
  19. package/dist/lifecycle/markets.d.ts.map +1 -1
  20. package/dist/lifecycle/markets.js +20 -3
  21. package/dist/lifecycle/markets.js.map +1 -1
  22. package/dist/lifecycle/planner.d.ts.map +1 -1
  23. package/dist/lifecycle/planner.js +42 -22
  24. package/dist/lifecycle/planner.js.map +1 -1
  25. package/dist/lifecycle/presets.d.ts +4 -2
  26. package/dist/lifecycle/presets.d.ts.map +1 -1
  27. package/dist/lifecycle/presets.js +11 -4
  28. package/dist/lifecycle/presets.js.map +1 -1
  29. package/dist/lifecycle/progress.d.ts.map +1 -1
  30. package/dist/lifecycle/progress.js +26 -5
  31. package/dist/lifecycle/progress.js.map +1 -1
  32. package/dist/lifecycle/simulation.d.ts.map +1 -1
  33. package/dist/lifecycle/simulation.js +4 -1
  34. package/dist/lifecycle/simulation.js.map +1 -1
  35. package/dist/lifecycle/types.d.ts +11 -1
  36. package/dist/lifecycle/types.d.ts.map +1 -1
  37. package/dist/lifecycle/types.js.map +1 -1
  38. package/dist/lifecycle/ufg-abi.d.ts +2386 -0
  39. package/dist/lifecycle/ufg-abi.d.ts.map +1 -0
  40. package/dist/lifecycle/ufg-abi.js +171 -0
  41. package/dist/lifecycle/ufg-abi.js.map +1 -0
  42. package/dist/lifecycle/ufg-config.d.ts +38 -0
  43. package/dist/lifecycle/ufg-config.d.ts.map +1 -0
  44. package/dist/lifecycle/ufg-config.js +75 -0
  45. package/dist/lifecycle/ufg-config.js.map +1 -0
  46. package/dist/lifecycle/ufg.d.ts +21 -0
  47. package/dist/lifecycle/ufg.d.ts.map +1 -0
  48. package/dist/lifecycle/ufg.js +98 -0
  49. package/dist/lifecycle/ufg.js.map +1 -0
  50. package/docs/launch-lifecycle.md +138 -0
  51. package/examples/README.md +16 -2
  52. package/examples/ufg-launch-config.ts +31 -0
  53. package/package.json +1 -1
  54. package/src/lifecycle/abi.ts +1 -0
  55. package/src/lifecycle/deployments/ufg-dynamic-pool-20261021.ts +74 -0
  56. package/src/lifecycle/deployments/ufg-fixed-pool-20261021.ts +74 -0
  57. package/src/lifecycle/index.ts +1 -0
  58. package/src/lifecycle/markets.ts +16 -3
  59. package/src/lifecycle/planner.ts +37 -22
  60. package/src/lifecycle/presets.ts +11 -4
  61. package/src/lifecycle/progress.ts +22 -5
  62. package/src/lifecycle/simulation.ts +3 -1
  63. package/src/lifecycle/types.ts +6 -1
  64. package/src/lifecycle/ufg-abi.ts +173 -0
  65. package/src/lifecycle/ufg-config.ts +77 -0
  66. package/src/lifecycle/ufg.ts +86 -0
@@ -0,0 +1,173 @@
1
+ // Complete UFG ABIs; generated by scripts/generate-ufg-presets.mjs from protocol artifacts.
2
+ export const ufgLaunchProxyV1Abi = [
3
+ {"type":"constructor","inputs":[{"name":"orchestrator_","type":"address"},{"name":"registry_","type":"address"},{"name":"treasuryFactory_","type":"address"}],"stateMutability":"nonpayable"},
4
+ {"type":"receive","stateMutability":"payable"},
5
+ {"type":"function","name":"activateLaunch","inputs":[{"name":"plan","type":"tuple","components":[{"name":"chainId","type":"uint256"},{"name":"orchestrator","type":"address"},{"name":"creator","type":"address"},{"name":"nonce","type":"uint256"},{"name":"token","type":"tuple","components":[{"name":"kind","type":"uint8"},{"name":"rewardMode","type":"uint8"},{"name":"name","type":"string"},{"name":"symbol","type":"string"},{"name":"supply","type":"uint256"},{"name":"nftUnit","type":"uint256"},{"name":"metadataURI","type":"string"},{"name":"salt","type":"bytes32"},{"name":"inventoryRecipient","type":"address"},{"name":"burnOnCancel","type":"bool"}]},{"name":"funding","type":"tuple[]","components":[{"name":"asset","type":"address"},{"name":"amount","type":"uint256"},{"name":"kind","type":"uint8"},{"name":"inputAsset","type":"address"},{"name":"inputAmount","type":"uint256"},{"name":"target","type":"address"},{"name":"data","type":"bytes"}]},{"name":"feeAssets","type":"tuple[]","components":[{"name":"asset","type":"address"},{"name":"ownerBps","type":"uint16"},{"name":"rewardsBps","type":"uint16"},{"name":"burnBps","type":"uint16"}]},{"name":"markets","type":"tuple[]","components":[{"name":"adapterId","type":"bytes32"},{"name":"profileId","type":"bytes32"},{"name":"quoteAsset","type":"address"},{"name":"tokenBudget","type":"uint256"},{"name":"configVersion","type":"uint32"},{"name":"config","type":"bytes"}]},{"name":"buys","type":"tuple[]","components":[{"name":"marketIndex","type":"uint32"},{"name":"quoteAmountIn","type":"uint256"},{"name":"minTokenOut","type":"uint256"},{"name":"recipient","type":"address"},{"name":"sqrtPriceLimitX96","type":"uint160"}]},{"name":"deadline","type":"uint256"},{"name":"executorFeeBps","type":"uint16"}]}],"outputs":[{"name":"receipt","type":"tuple","components":[{"name":"launchId","type":"bytes32"},{"name":"planHash","type":"bytes32"},{"name":"token","type":"address"},{"name":"feeHub","type":"address"},{"name":"rewards","type":"address"},{"name":"marketCount","type":"uint32"},{"name":"positionCount","type":"uint32"},{"name":"quoteSpent","type":"uint256[]"},{"name":"tokenOut","type":"uint256[]"}]}],"stateMutability":"nonpayable"},
6
+ {"type":"function","name":"beginLaunch","inputs":[{"name":"plan","type":"tuple","components":[{"name":"chainId","type":"uint256"},{"name":"orchestrator","type":"address"},{"name":"creator","type":"address"},{"name":"nonce","type":"uint256"},{"name":"token","type":"tuple","components":[{"name":"kind","type":"uint8"},{"name":"rewardMode","type":"uint8"},{"name":"name","type":"string"},{"name":"symbol","type":"string"},{"name":"supply","type":"uint256"},{"name":"nftUnit","type":"uint256"},{"name":"metadataURI","type":"string"},{"name":"salt","type":"bytes32"},{"name":"inventoryRecipient","type":"address"},{"name":"burnOnCancel","type":"bool"}]},{"name":"funding","type":"tuple[]","components":[{"name":"asset","type":"address"},{"name":"amount","type":"uint256"},{"name":"kind","type":"uint8"},{"name":"inputAsset","type":"address"},{"name":"inputAmount","type":"uint256"},{"name":"target","type":"address"},{"name":"data","type":"bytes"}]},{"name":"feeAssets","type":"tuple[]","components":[{"name":"asset","type":"address"},{"name":"ownerBps","type":"uint16"},{"name":"rewardsBps","type":"uint16"},{"name":"burnBps","type":"uint16"}]},{"name":"markets","type":"tuple[]","components":[{"name":"adapterId","type":"bytes32"},{"name":"profileId","type":"bytes32"},{"name":"quoteAsset","type":"address"},{"name":"tokenBudget","type":"uint256"},{"name":"configVersion","type":"uint32"},{"name":"config","type":"bytes"}]},{"name":"buys","type":"tuple[]","components":[{"name":"marketIndex","type":"uint32"},{"name":"quoteAmountIn","type":"uint256"},{"name":"minTokenOut","type":"uint256"},{"name":"recipient","type":"address"},{"name":"sqrtPriceLimitX96","type":"uint160"}]},{"name":"deadline","type":"uint256"},{"name":"executorFeeBps","type":"uint16"}]},{"name":"mode","type":"uint8"},{"name":"config","type":"tuple","components":[{"name":"treasuryShareBps","type":"uint16"},{"name":"exitFeeBps","type":"uint16"},{"name":"reserveAssets","type":"address[]"}]}],"outputs":[{"name":"progress","type":"tuple","components":[{"name":"launchId","type":"bytes32"},{"name":"planHash","type":"bytes32"},{"name":"creator","type":"address"},{"name":"nonce","type":"uint256"},{"name":"mode","type":"uint8"},{"name":"phase","type":"uint8"},{"name":"token","type":"address"},{"name":"feeHub","type":"address"},{"name":"rewards","type":"address"},{"name":"preparedMarkets","type":"uint32"},{"name":"marketCount","type":"uint32"},{"name":"buyCount","type":"uint32"},{"name":"positionCount","type":"uint32"},{"name":"deadline","type":"uint256"}]}],"stateMutability":"payable"},
7
+ {"type":"function","name":"cancelLaunch","inputs":[{"name":"plan","type":"tuple","components":[{"name":"chainId","type":"uint256"},{"name":"orchestrator","type":"address"},{"name":"creator","type":"address"},{"name":"nonce","type":"uint256"},{"name":"token","type":"tuple","components":[{"name":"kind","type":"uint8"},{"name":"rewardMode","type":"uint8"},{"name":"name","type":"string"},{"name":"symbol","type":"string"},{"name":"supply","type":"uint256"},{"name":"nftUnit","type":"uint256"},{"name":"metadataURI","type":"string"},{"name":"salt","type":"bytes32"},{"name":"inventoryRecipient","type":"address"},{"name":"burnOnCancel","type":"bool"}]},{"name":"funding","type":"tuple[]","components":[{"name":"asset","type":"address"},{"name":"amount","type":"uint256"},{"name":"kind","type":"uint8"},{"name":"inputAsset","type":"address"},{"name":"inputAmount","type":"uint256"},{"name":"target","type":"address"},{"name":"data","type":"bytes"}]},{"name":"feeAssets","type":"tuple[]","components":[{"name":"asset","type":"address"},{"name":"ownerBps","type":"uint16"},{"name":"rewardsBps","type":"uint16"},{"name":"burnBps","type":"uint16"}]},{"name":"markets","type":"tuple[]","components":[{"name":"adapterId","type":"bytes32"},{"name":"profileId","type":"bytes32"},{"name":"quoteAsset","type":"address"},{"name":"tokenBudget","type":"uint256"},{"name":"configVersion","type":"uint32"},{"name":"config","type":"bytes"}]},{"name":"buys","type":"tuple[]","components":[{"name":"marketIndex","type":"uint32"},{"name":"quoteAmountIn","type":"uint256"},{"name":"minTokenOut","type":"uint256"},{"name":"recipient","type":"address"},{"name":"sqrtPriceLimitX96","type":"uint160"}]},{"name":"deadline","type":"uint256"},{"name":"executorFeeBps","type":"uint16"}]}],"outputs":[],"stateMutability":"nonpayable"},
8
+ {"type":"function","name":"feeOwnerRegistry","inputs":[],"outputs":[{"name":"","type":"address"}],"stateMutability":"view"},
9
+ {"type":"function","name":"handoffFeeOwnership","inputs":[{"name":"token","type":"address"},{"name":"adapter","type":"address"}],"outputs":[],"stateMutability":"nonpayable"},
10
+ {"type":"function","name":"launchAtomic","inputs":[{"name":"plan","type":"tuple","components":[{"name":"chainId","type":"uint256"},{"name":"orchestrator","type":"address"},{"name":"creator","type":"address"},{"name":"nonce","type":"uint256"},{"name":"token","type":"tuple","components":[{"name":"kind","type":"uint8"},{"name":"rewardMode","type":"uint8"},{"name":"name","type":"string"},{"name":"symbol","type":"string"},{"name":"supply","type":"uint256"},{"name":"nftUnit","type":"uint256"},{"name":"metadataURI","type":"string"},{"name":"salt","type":"bytes32"},{"name":"inventoryRecipient","type":"address"},{"name":"burnOnCancel","type":"bool"}]},{"name":"funding","type":"tuple[]","components":[{"name":"asset","type":"address"},{"name":"amount","type":"uint256"},{"name":"kind","type":"uint8"},{"name":"inputAsset","type":"address"},{"name":"inputAmount","type":"uint256"},{"name":"target","type":"address"},{"name":"data","type":"bytes"}]},{"name":"feeAssets","type":"tuple[]","components":[{"name":"asset","type":"address"},{"name":"ownerBps","type":"uint16"},{"name":"rewardsBps","type":"uint16"},{"name":"burnBps","type":"uint16"}]},{"name":"markets","type":"tuple[]","components":[{"name":"adapterId","type":"bytes32"},{"name":"profileId","type":"bytes32"},{"name":"quoteAsset","type":"address"},{"name":"tokenBudget","type":"uint256"},{"name":"configVersion","type":"uint32"},{"name":"config","type":"bytes"}]},{"name":"buys","type":"tuple[]","components":[{"name":"marketIndex","type":"uint32"},{"name":"quoteAmountIn","type":"uint256"},{"name":"minTokenOut","type":"uint256"},{"name":"recipient","type":"address"},{"name":"sqrtPriceLimitX96","type":"uint160"}]},{"name":"deadline","type":"uint256"},{"name":"executorFeeBps","type":"uint16"}]},{"name":"config","type":"tuple","components":[{"name":"treasuryShareBps","type":"uint16"},{"name":"exitFeeBps","type":"uint16"},{"name":"reserveAssets","type":"address[]"}]}],"outputs":[{"name":"receipt","type":"tuple","components":[{"name":"launchId","type":"bytes32"},{"name":"planHash","type":"bytes32"},{"name":"token","type":"address"},{"name":"feeHub","type":"address"},{"name":"rewards","type":"address"},{"name":"marketCount","type":"uint32"},{"name":"positionCount","type":"uint32"},{"name":"quoteSpent","type":"uint256[]"},{"name":"tokenOut","type":"uint256[]"}]}],"stateMutability":"payable"},
11
+ {"type":"function","name":"launchConfigHash","inputs":[{"name":"launchId","type":"bytes32"}],"outputs":[{"name":"configHash","type":"bytes32"}],"stateMutability":"view"},
12
+ {"type":"function","name":"nonceOf","inputs":[{"name":"principal","type":"address"},{"name":"nonce","type":"uint96"}],"outputs":[{"name":"","type":"uint256"}],"stateMutability":"pure"},
13
+ {"type":"function","name":"orchestrator","inputs":[],"outputs":[{"name":"","type":"address"}],"stateMutability":"view"},
14
+ {"type":"function","name":"prepareMarkets","inputs":[{"name":"plan","type":"tuple","components":[{"name":"chainId","type":"uint256"},{"name":"orchestrator","type":"address"},{"name":"creator","type":"address"},{"name":"nonce","type":"uint256"},{"name":"token","type":"tuple","components":[{"name":"kind","type":"uint8"},{"name":"rewardMode","type":"uint8"},{"name":"name","type":"string"},{"name":"symbol","type":"string"},{"name":"supply","type":"uint256"},{"name":"nftUnit","type":"uint256"},{"name":"metadataURI","type":"string"},{"name":"salt","type":"bytes32"},{"name":"inventoryRecipient","type":"address"},{"name":"burnOnCancel","type":"bool"}]},{"name":"funding","type":"tuple[]","components":[{"name":"asset","type":"address"},{"name":"amount","type":"uint256"},{"name":"kind","type":"uint8"},{"name":"inputAsset","type":"address"},{"name":"inputAmount","type":"uint256"},{"name":"target","type":"address"},{"name":"data","type":"bytes"}]},{"name":"feeAssets","type":"tuple[]","components":[{"name":"asset","type":"address"},{"name":"ownerBps","type":"uint16"},{"name":"rewardsBps","type":"uint16"},{"name":"burnBps","type":"uint16"}]},{"name":"markets","type":"tuple[]","components":[{"name":"adapterId","type":"bytes32"},{"name":"profileId","type":"bytes32"},{"name":"quoteAsset","type":"address"},{"name":"tokenBudget","type":"uint256"},{"name":"configVersion","type":"uint32"},{"name":"config","type":"bytes"}]},{"name":"buys","type":"tuple[]","components":[{"name":"marketIndex","type":"uint32"},{"name":"quoteAmountIn","type":"uint256"},{"name":"minTokenOut","type":"uint256"},{"name":"recipient","type":"address"},{"name":"sqrtPriceLimitX96","type":"uint160"}]},{"name":"deadline","type":"uint256"},{"name":"executorFeeBps","type":"uint16"}]},{"name":"firstMarket","type":"uint32"},{"name":"count","type":"uint32"}],"outputs":[],"stateMutability":"nonpayable"},
15
+ {"type":"function","name":"principalOf","inputs":[{"name":"launchId","type":"bytes32"}],"outputs":[{"name":"principal","type":"address"}],"stateMutability":"view"},
16
+ {"type":"function","name":"treasuryFactory","inputs":[],"outputs":[{"name":"","type":"address"}],"stateMutability":"view"},
17
+ {"type":"event","name":"LaunchConfigBound","inputs":[{"name":"launchId","type":"bytes32","indexed":true},{"name":"planHash","type":"bytes32","indexed":false},{"name":"configHash","type":"bytes32","indexed":false}],"anonymous":false},
18
+ {"type":"error","name":"InexactTransfer","inputs":[]},
19
+ {"type":"error","name":"InvalidConfiguration","inputs":[]},
20
+ {"type":"error","name":"InvalidNonce","inputs":[]},
21
+ {"type":"error","name":"InvalidPlan","inputs":[]},
22
+ {"type":"error","name":"PlanMismatch","inputs":[]},
23
+ {"type":"error","name":"Reentrancy","inputs":[]},
24
+ {"type":"error","name":"TooManyReserves","inputs":[]},
25
+ {"type":"error","name":"Unauthorized","inputs":[]},
26
+ ] as const;
27
+
28
+ export const ufgTreasuryFactoryV1Abi = [
29
+ {"type":"constructor","inputs":[{"name":"hubFactory_","type":"address"},{"name":"approvedProxy_","type":"address"},{"name":"collectorDeployer_","type":"address"},{"name":"splitter_","type":"address"},{"name":"platformShareBps_","type":"uint16"},{"name":"ratePerSecond_","type":"uint256"},{"name":"upstreamFactory_","type":"address"},{"name":"upstreamFactoryCodeHash_","type":"bytes32"}],"stateMutability":"nonpayable"},
30
+ {"type":"function","name":"MAX_INIT_CODE_SIZE","inputs":[],"outputs":[{"name":"","type":"uint256"}],"stateMutability":"view"},
31
+ {"type":"function","name":"MAX_PLATFORM_SHARE_BPS","inputs":[],"outputs":[{"name":"","type":"uint16"}],"stateMutability":"view"},
32
+ {"type":"function","name":"MAX_RUNTIME_SIZE","inputs":[],"outputs":[{"name":"","type":"uint256"}],"stateMutability":"view"},
33
+ {"type":"function","name":"approvedProxy","inputs":[],"outputs":[{"name":"","type":"address"}],"stateMutability":"view"},
34
+ {"type":"function","name":"approvedProxyCodeHash","inputs":[],"outputs":[{"name":"","type":"bytes32"}],"stateMutability":"view"},
35
+ {"type":"function","name":"collectorDeployer","inputs":[],"outputs":[{"name":"","type":"address"}],"stateMutability":"view"},
36
+ {"type":"function","name":"configHash","inputs":[{"name":"token","type":"address"}],"outputs":[{"name":"hash","type":"bytes32"}],"stateMutability":"view"},
37
+ {"type":"function","name":"decodeLaunchConfig","inputs":[{"name":"encoded","type":"bytes"},{"name":"canonicalPrefix","type":"bytes"}],"outputs":[{"name":"","type":"tuple","components":[{"name":"treasuryShareBps","type":"uint16"},{"name":"exitFeeBps","type":"uint16"},{"name":"reserveAssets","type":"address[]"}]}],"stateMutability":"pure"},
38
+ {"type":"function","name":"deployedCodeHash","inputs":[{"name":"deployed","type":"address"}],"outputs":[{"name":"hash","type":"bytes32"}],"stateMutability":"view"},
39
+ {"type":"function","name":"feeOwnerRegistry","inputs":[],"outputs":[{"name":"","type":"address"}],"stateMutability":"view"},
40
+ {"type":"function","name":"fundingAdapterOf","inputs":[{"name":"token","type":"address"}],"outputs":[{"name":"adapter","type":"address"}],"stateMutability":"view"},
41
+ {"type":"function","name":"getOrCreate","inputs":[{"name":"token","type":"address"},{"name":"hub","type":"address"},{"name":"config","type":"tuple","components":[{"name":"treasuryShareBps","type":"uint16"},{"name":"exitFeeBps","type":"uint16"},{"name":"reserveAssets","type":"address[]"}]},{"name":"feeMode","type":"uint8"},{"name":"lpFeePips","type":"uint24"}],"outputs":[{"name":"adapter","type":"address"},{"name":"treasury","type":"address"}],"stateMutability":"nonpayable"},
42
+ {"type":"function","name":"hubFactory","inputs":[],"outputs":[{"name":"","type":"address"}],"stateMutability":"view"},
43
+ {"type":"function","name":"platformShareBps","inputs":[],"outputs":[{"name":"","type":"uint16"}],"stateMutability":"view"},
44
+ {"type":"function","name":"ratePerSecond","inputs":[],"outputs":[{"name":"","type":"uint256"}],"stateMutability":"view"},
45
+ {"type":"function","name":"splitter","inputs":[],"outputs":[{"name":"","type":"address"}],"stateMutability":"view"},
46
+ {"type":"function","name":"treasuryOf","inputs":[{"name":"token","type":"address"}],"outputs":[{"name":"treasury","type":"address"}],"stateMutability":"view"},
47
+ {"type":"function","name":"upstreamFactory","inputs":[],"outputs":[{"name":"","type":"address"}],"stateMutability":"view"},
48
+ {"type":"function","name":"upstreamFactoryCodeHash","inputs":[],"outputs":[{"name":"","type":"bytes32"}],"stateMutability":"view"},
49
+ {"type":"function","name":"validateMarketLaunchConfig","inputs":[{"name":"encoded","type":"bytes"},{"name":"canonicalPrefix","type":"bytes"},{"name":"token","type":"address"},{"name":"quote","type":"address"}],"outputs":[{"name":"launch","type":"tuple","components":[{"name":"treasuryShareBps","type":"uint16"},{"name":"exitFeeBps","type":"uint16"},{"name":"reserveAssets","type":"address[]"}]}],"stateMutability":"view"},
50
+ {"type":"event","name":"TreasuryCreated","inputs":[{"name":"token","type":"address","indexed":true},{"name":"hub","type":"address","indexed":true},{"name":"treasury","type":"address","indexed":true},{"name":"fundingAdapter","type":"address","indexed":false},{"name":"configHash","type":"bytes32","indexed":false}],"anonymous":false},
51
+ {"type":"error","name":"DeploymentFailed","inputs":[]},
52
+ {"type":"error","name":"InconsistentConfiguration","inputs":[]},
53
+ {"type":"error","name":"InitCodeTooLarge","inputs":[]},
54
+ {"type":"error","name":"InvalidConfiguration","inputs":[]},
55
+ {"type":"error","name":"InvalidHub","inputs":[]},
56
+ {"type":"error","name":"InvalidUFGConfiguration","inputs":[]},
57
+ {"type":"error","name":"Reentrancy","inputs":[]},
58
+ {"type":"error","name":"RuntimeCodeTooLarge","inputs":[]},
59
+ {"type":"error","name":"Unauthorized","inputs":[]},
60
+ {"type":"error","name":"UnlockedLaunch","inputs":[]},
61
+ ] as const;
62
+
63
+ export const ufgBlackMarketFactoryAbi = [
64
+ {"type":"constructor","inputs":[{"name":"tokenFactory_","type":"address"},{"name":"hubFactory_","type":"address"},{"name":"splitter_","type":"address"},{"name":"platformShareBps_","type":"uint16"},{"name":"ratePerSecond_","type":"uint256"}],"stateMutability":"nonpayable"},
65
+ {"type":"function","name":"ABYSS_HUB_FACTORY","inputs":[],"outputs":[{"name":"","type":"address"}],"stateMutability":"view"},
66
+ {"type":"function","name":"ABYSS_TOKEN_FACTORY","inputs":[],"outputs":[{"name":"","type":"address"}],"stateMutability":"view"},
67
+ {"type":"function","name":"MAX_EXIT_FEE_BPS","inputs":[],"outputs":[{"name":"","type":"uint16"}],"stateMutability":"view"},
68
+ {"type":"function","name":"MAX_PLATFORM_SHARE_BPS","inputs":[],"outputs":[{"name":"","type":"uint16"}],"stateMutability":"view"},
69
+ {"type":"function","name":"MAX_RATE_PER_SECOND","inputs":[],"outputs":[{"name":"","type":"uint256"}],"stateMutability":"view"},
70
+ {"type":"function","name":"PLATFORM_SHARE_BPS","inputs":[],"outputs":[{"name":"","type":"uint16"}],"stateMutability":"view"},
71
+ {"type":"function","name":"RATE_PER_SECOND","inputs":[],"outputs":[{"name":"","type":"uint256"}],"stateMutability":"view"},
72
+ {"type":"function","name":"SPLITTER","inputs":[],"outputs":[{"name":"","type":"address"}],"stateMutability":"view"},
73
+ {"type":"function","name":"deploy","inputs":[{"name":"token","type":"address"},{"name":"canonicalHub","type":"address"},{"name":"fundingAdapter","type":"address"},{"name":"rewardAssets","type":"address[]"},{"name":"exitFeeBps","type":"uint16"}],"outputs":[{"name":"treasury","type":"address"}],"stateMutability":"nonpayable"},
74
+ {"type":"function","name":"launchCount","inputs":[],"outputs":[{"name":"","type":"uint256"}],"stateMutability":"view"},
75
+ {"type":"function","name":"predict","inputs":[{"name":"token","type":"address"},{"name":"canonicalHub","type":"address"},{"name":"fundingAdapter","type":"address"},{"name":"rewardAssets","type":"address[]"},{"name":"exitFeeBps","type":"uint16"}],"outputs":[{"name":"","type":"address"}],"stateMutability":"view"},
76
+ {"type":"function","name":"treasuries","inputs":[{"name":"","type":"address"}],"outputs":[{"name":"","type":"address"}],"stateMutability":"view"},
77
+ {"type":"event","name":"FundingAdapterBound","inputs":[{"name":"token","type":"address","indexed":true},{"name":"canonicalHub","type":"address","indexed":true},{"name":"fundingAdapter","type":"address","indexed":true},{"name":"treasury","type":"address","indexed":false}],"anonymous":false},
78
+ {"type":"event","name":"TreasuryDeployed","inputs":[{"name":"token","type":"address","indexed":true},{"name":"hub","type":"address","indexed":true},{"name":"treasury","type":"address","indexed":true},{"name":"rewardAssets","type":"address[]","indexed":false},{"name":"exitFeeBps","type":"uint16","indexed":false}],"anonymous":false},
79
+ {"type":"error","name":"AlreadyDeployed","inputs":[]},
80
+ {"type":"error","name":"BadConfiguration","inputs":[]},
81
+ {"type":"error","name":"BadExitFee","inputs":[]},
82
+ {"type":"error","name":"BadFundingAdapter","inputs":[]},
83
+ {"type":"error","name":"BountyNotZero","inputs":[]},
84
+ {"type":"error","name":"HubTokenMismatch","inputs":[]},
85
+ {"type":"error","name":"NotTokenFactory","inputs":[]},
86
+ {"type":"error","name":"UnknownHub","inputs":[]},
87
+ ] as const;
88
+
89
+ export const ufgBlackMarketTreasuryAbi = [
90
+ {"type":"constructor","inputs":[{"name":"token","type":"address"},{"name":"hub","type":"address"},{"name":"assets_","type":"address[]"},{"name":"exitFeeBps","type":"uint16"},{"name":"splitter","type":"address"},{"name":"platformShareBps","type":"uint16"},{"name":"ratePerSecond","type":"uint256"}],"stateMutability":"nonpayable"},
91
+ {"type":"function","name":"DEAD","inputs":[],"outputs":[{"name":"","type":"address"}],"stateMutability":"view"},
92
+ {"type":"function","name":"EXIT_FEE_BPS","inputs":[],"outputs":[{"name":"","type":"uint16"}],"stateMutability":"view"},
93
+ {"type":"function","name":"HUB","inputs":[],"outputs":[{"name":"","type":"address"}],"stateMutability":"view"},
94
+ {"type":"function","name":"LIQUIDATION_LTV_BPS","inputs":[],"outputs":[{"name":"","type":"uint16"}],"stateMutability":"view"},
95
+ {"type":"function","name":"LTV_BPS","inputs":[],"outputs":[{"name":"","type":"uint16"}],"stateMutability":"view"},
96
+ {"type":"function","name":"MAX_ASSETS","inputs":[],"outputs":[{"name":"","type":"uint256"}],"stateMutability":"view"},
97
+ {"type":"function","name":"MAX_EXIT_FEE_BPS","inputs":[],"outputs":[{"name":"","type":"uint16"}],"stateMutability":"view"},
98
+ {"type":"function","name":"MAX_INDEX","inputs":[],"outputs":[{"name":"","type":"uint256"}],"stateMutability":"view"},
99
+ {"type":"function","name":"MAX_RATE_PER_SECOND","inputs":[],"outputs":[{"name":"","type":"uint256"}],"stateMutability":"view"},
100
+ {"type":"function","name":"MIN_DEBT","inputs":[],"outputs":[{"name":"","type":"uint256"}],"stateMutability":"view"},
101
+ {"type":"function","name":"PLATFORM_SHARE_BPS","inputs":[],"outputs":[{"name":"","type":"uint16"}],"stateMutability":"view"},
102
+ {"type":"function","name":"RATE_PER_SECOND","inputs":[],"outputs":[{"name":"","type":"uint256"}],"stateMutability":"view"},
103
+ {"type":"function","name":"SPLITTER","inputs":[],"outputs":[{"name":"","type":"address"}],"stateMutability":"view"},
104
+ {"type":"function","name":"TOKEN","inputs":[],"outputs":[{"name":"","type":"address"}],"stateMutability":"view"},
105
+ {"type":"function","name":"addCollateral","inputs":[{"name":"amount","type":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},
106
+ {"type":"function","name":"annualRate","inputs":[],"outputs":[{"name":"","type":"uint256"}],"stateMutability":"view"},
107
+ {"type":"function","name":"assets","inputs":[],"outputs":[{"name":"","type":"address[]"}],"stateMutability":"view"},
108
+ {"type":"function","name":"backing","inputs":[{"name":"asset","type":"address"}],"outputs":[{"name":"","type":"uint256"}],"stateMutability":"view"},
109
+ {"type":"function","name":"borrow","inputs":[{"name":"amounts","type":"uint256[]"},{"name":"to","type":"address"}],"outputs":[],"stateMutability":"nonpayable"},
110
+ {"type":"function","name":"burnStray","inputs":[],"outputs":[],"stateMutability":"nonpayable"},
111
+ {"type":"function","name":"collect","inputs":[],"outputs":[],"stateMutability":"nonpayable"},
112
+ {"type":"function","name":"debtOf","inputs":[{"name":"account","type":"address"}],"outputs":[{"name":"out","type":"uint256[]"}],"stateMutability":"view"},
113
+ {"type":"function","name":"distributor","inputs":[],"outputs":[{"name":"","type":"address"}],"stateMutability":"view"},
114
+ {"type":"function","name":"effectiveSupply","inputs":[],"outputs":[{"name":"","type":"uint256"}],"stateMutability":"view"},
115
+ {"type":"function","name":"interestIndex","inputs":[],"outputs":[{"name":"","type":"uint256"}],"stateMutability":"view"},
116
+ {"type":"function","name":"isLiquidatable","inputs":[{"name":"account","type":"address"}],"outputs":[{"name":"","type":"bool"}],"stateMutability":"view"},
117
+ {"type":"function","name":"lastAccrual","inputs":[],"outputs":[{"name":"","type":"uint256"}],"stateMutability":"view"},
118
+ {"type":"function","name":"liquid","inputs":[{"name":"asset","type":"address"}],"outputs":[{"name":"","type":"uint256"}],"stateMutability":"view"},
119
+ {"type":"function","name":"liquidate","inputs":[{"name":"account","type":"address"}],"outputs":[],"stateMutability":"nonpayable"},
120
+ {"type":"function","name":"maxBorrow","inputs":[{"name":"account","type":"address"}],"outputs":[{"name":"out","type":"uint256[]"}],"stateMutability":"view"},
121
+ {"type":"function","name":"notifyRewardAmounts","inputs":[{"name":"amounts","type":"uint256[]"}],"outputs":[],"stateMutability":"nonpayable"},
122
+ {"type":"function","name":"originationCap","inputs":[{"name":"collateral","type":"uint256"}],"outputs":[{"name":"out","type":"uint256[]"}],"stateMutability":"view"},
123
+ {"type":"function","name":"owed","inputs":[{"name":"","type":"address"}],"outputs":[{"name":"","type":"uint256"}],"stateMutability":"view"},
124
+ {"type":"function","name":"positionOf","inputs":[{"name":"account","type":"address"}],"outputs":[{"name":"collateral","type":"uint256"},{"name":"principal","type":"uint256[]"},{"name":"debt","type":"uint256[]"}],"stateMutability":"view"},
125
+ {"type":"function","name":"principalOutstanding","inputs":[{"name":"","type":"address"}],"outputs":[{"name":"","type":"uint256"}],"stateMutability":"view"},
126
+ {"type":"function","name":"quoteRedeem","inputs":[{"name":"amount","type":"uint256"}],"outputs":[{"name":"out","type":"uint256[]"}],"stateMutability":"view"},
127
+ {"type":"function","name":"redeem","inputs":[{"name":"amount","type":"uint256"},{"name":"minOuts","type":"uint256[]"},{"name":"to","type":"address"}],"outputs":[],"stateMutability":"nonpayable"},
128
+ {"type":"function","name":"redeemSkipping","inputs":[{"name":"amount","type":"uint256"},{"name":"minOuts","type":"uint256[]"},{"name":"to","type":"address"},{"name":"skipMask","type":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},
129
+ {"type":"function","name":"releasePlatformFees","inputs":[],"outputs":[],"stateMutability":"nonpayable"},
130
+ {"type":"function","name":"releasePlatformFeesFor","inputs":[{"name":"assets_","type":"address[]"}],"outputs":[],"stateMutability":"nonpayable"},
131
+ {"type":"function","name":"repay","inputs":[{"name":"account","type":"address"},{"name":"amounts","type":"uint256[]"}],"outputs":[],"stateMutability":"nonpayable"},
132
+ {"type":"function","name":"reserve","inputs":[{"name":"asset","type":"address"}],"outputs":[{"name":"","type":"uint256"}],"stateMutability":"view"},
133
+ {"type":"function","name":"rewardAssets","inputs":[],"outputs":[{"name":"","type":"address[]"}],"stateMutability":"view"},
134
+ {"type":"function","name":"rewardAvailableBalance","inputs":[{"name":"asset","type":"address"}],"outputs":[{"name":"","type":"uint256"}],"stateMutability":"view"},
135
+ {"type":"function","name":"totalCollateral","inputs":[],"outputs":[{"name":"","type":"uint256"}],"stateMutability":"view"},
136
+ {"type":"function","name":"withdrawCollateral","inputs":[{"name":"amount","type":"uint256"},{"name":"to","type":"address"}],"outputs":[],"stateMutability":"nonpayable"},
137
+ {"type":"event","name":"AssetsSkipped","inputs":[{"name":"caller","type":"address","indexed":true},{"name":"skipMask","type":"uint256","indexed":false}],"anonymous":false},
138
+ {"type":"event","name":"CollateralAdded","inputs":[{"name":"account","type":"address","indexed":true},{"name":"amount","type":"uint256","indexed":false}],"anonymous":false},
139
+ {"type":"event","name":"CollateralWithdrawn","inputs":[{"name":"account","type":"address","indexed":true},{"name":"to","type":"address","indexed":true},{"name":"amount","type":"uint256","indexed":false}],"anonymous":false},
140
+ {"type":"event","name":"CollectFailed","inputs":[{"name":"reason","type":"bytes","indexed":false}],"anonymous":false},
141
+ {"type":"event","name":"Funded","inputs":[{"name":"asset","type":"address","indexed":true},{"name":"amount","type":"uint256","indexed":false},{"name":"platformPart","type":"uint256","indexed":false}],"anonymous":false},
142
+ {"type":"event","name":"PlatformFeesReleased","inputs":[{"name":"asset","type":"address","indexed":true},{"name":"amount","type":"uint256","indexed":false}],"anonymous":false},
143
+ {"type":"event","name":"Redeemed","inputs":[{"name":"caller","type":"address","indexed":true},{"name":"to","type":"address","indexed":true},{"name":"burned","type":"uint256","indexed":false},{"name":"paid","type":"uint256[]","indexed":false},{"name":"fee","type":"uint256[]","indexed":false}],"anonymous":false},
144
+ {"type":"event","name":"ReserveLoanBorrowed","inputs":[{"name":"account","type":"address","indexed":true},{"name":"to","type":"address","indexed":true},{"name":"asset","type":"address","indexed":true},{"name":"amount","type":"uint256","indexed":false}],"anonymous":false},
145
+ {"type":"event","name":"ReserveLoanLiquidated","inputs":[{"name":"account","type":"address","indexed":true},{"name":"caller","type":"address","indexed":true},{"name":"burned","type":"uint256","indexed":false},{"name":"assets","type":"address[]","indexed":false},{"name":"principals","type":"uint256[]","indexed":false}],"anonymous":false},
146
+ {"type":"event","name":"ReserveLoanRepaid","inputs":[{"name":"account","type":"address","indexed":true},{"name":"payer","type":"address","indexed":true},{"name":"asset","type":"address","indexed":true},{"name":"principal","type":"uint256","indexed":false},{"name":"interest","type":"uint256","indexed":false}],"anonymous":false},
147
+ {"type":"event","name":"StrayBurned","inputs":[{"name":"amount","type":"uint256","indexed":false}],"anonymous":false},
148
+ {"type":"error","name":"BadAmounts","inputs":[]},
149
+ {"type":"error","name":"BadAssets","inputs":[]},
150
+ {"type":"error","name":"BadExitFee","inputs":[]},
151
+ {"type":"error","name":"BadHub","inputs":[]},
152
+ {"type":"error","name":"BadRate","inputs":[]},
153
+ {"type":"error","name":"BadRecipient","inputs":[]},
154
+ {"type":"error","name":"BadShare","inputs":[]},
155
+ {"type":"error","name":"BadSkipMask","inputs":[]},
156
+ {"type":"error","name":"BadSplitter","inputs":[]},
157
+ {"type":"error","name":"BadToken","inputs":[]},
158
+ {"type":"error","name":"BelowMinDebt","inputs":[]},
159
+ {"type":"error","name":"ExceedsCap","inputs":[]},
160
+ {"type":"error","name":"IndexSaturated","inputs":[]},
161
+ {"type":"error","name":"InsufficientCollateral","inputs":[]},
162
+ {"type":"error","name":"InsufficientLiquidity","inputs":[]},
163
+ {"type":"error","name":"NoPosition","inputs":[]},
164
+ {"type":"error","name":"NotHub","inputs":[]},
165
+ {"type":"error","name":"NotLiquidatable","inputs":[]},
166
+ {"type":"error","name":"NothingToRepay","inputs":[]},
167
+ {"type":"error","name":"ReentrancyGuardReentrantCall","inputs":[]},
168
+ {"type":"error","name":"SafeERC20FailedOperation","inputs":[{"name":"token","type":"address"}]},
169
+ {"type":"error","name":"SlippageExceeded","inputs":[]},
170
+ {"type":"error","name":"ZeroAmount","inputs":[]},
171
+ {"type":"error","name":"ZeroPayout","inputs":[]},
172
+ {"type":"error","name":"ZeroSupply","inputs":[]},
173
+ ] as const;
@@ -0,0 +1,77 @@
1
+ import { decodeAbiParameters, encodeAbiParameters, getAddress, keccak256, type Address, type Hex } from "viem";
2
+ import type { LaunchPlanV1, LifecycleFeeAssetPolicyV2 } from "./schema.js";
3
+ import { LifecyclePlanningError } from "./types.js";
4
+
5
+ export const UFG_LAUNCH_PROXY_ADDRESS: Address = "0xf6673d859DE03eB74A0b01696Edb97f941dFD0CA";
6
+ export const UFG_TREASURY_FACTORY_ADDRESS: Address = "0x26Aa5D52134c8E6c4C01E9fb53A7568c0C64901F";
7
+ export const UFG_UPSTREAM_FACTORY_ADDRESS: Address = "0xA170b5A58C111334A7237F2Ea2c428ec5022f68E";
8
+ export const UFG_ORCHESTRATOR_ADDRESS: Address = "0x91560876033d568d25CDe98C78c33ff8FC43962c";
9
+ export const UFG_FIXED_PROFILE_ID: Hex = "0x5c6045af480814e469f3dba7c120d264047c9320b869c63a064536041a2dbae6";
10
+ export const UFG_DYNAMIC_PROFILE_ID: Hex = "0x03de8d5e38f2957d80ecb9f2e59d555601ff091dfb17bce84178956a2e8d9b41";
11
+ export const UFG_FIXED_ADAPTER_ID: Hex = "0x073a4d46af70a3d4f69641e4f9dcdc9d8c279cd443daff960bbdf65a3b5fc758";
12
+ export const UFG_DYNAMIC_ADAPTER_ID: Hex = "0xc0906e17625b48240a87a3afc6ee921b653bdacd72906a16b359d0776d938518";
13
+
14
+ export function isUfgProfile(profileId: Hex): boolean {
15
+ const id = profileId.toLowerCase();
16
+ return id === UFG_FIXED_PROFILE_ID || id === UFG_DYNAMIC_PROFILE_ID;
17
+ }
18
+
19
+ export type UfgLaunchConfig = { treasuryShareBps: number; exitFeeBps: number; reserveAssets: readonly Address[] };
20
+ export const ufgLaunchConfigComponents = [
21
+ { name: "treasuryShareBps", type: "uint16" }, { name: "exitFeeBps", type: "uint16" },
22
+ { name: "reserveAssets", type: "address[]" },
23
+ ] as const;
24
+
25
+ /** The proxy has seven reserve slots; its eighth fee asset is the launched token. */
26
+ export function validateUfgLaunchConfig(config: UfgLaunchConfig): void {
27
+ if (config.treasuryShareBps !== 10000 || !Number.isInteger(config.exitFeeBps) || config.exitFeeBps < 0 || config.exitFeeBps > 2000 || config.reserveAssets.length < 1 || config.reserveAssets.length > 7) {
28
+ throw new LifecyclePlanningError("INVALID_UFG_CONFIG", "UFG requires 10000 treasury bps, exit fee 0..2000 bps and one to seven reserves");
29
+ }
30
+ let previous = 0n;
31
+ for (const asset of config.reserveAssets) {
32
+ getAddress(asset);
33
+ if (BigInt(asset) <= previous) throw new LifecyclePlanningError("INVALID_UFG_CONFIG", "UFG reserves must be nonzero, unique and strictly ascending");
34
+ previous = BigInt(asset);
35
+ }
36
+ }
37
+
38
+ /** abi.encode(UFGLaunchConfigV1): one dynamic tuple, including its leading 0x20 offset. */
39
+ export function encodeUfgLaunchConfig(config: UfgLaunchConfig): Hex {
40
+ validateUfgLaunchConfig(config);
41
+ return encodeAbiParameters([{ type: "tuple", components: ufgLaunchConfigComponents }], [config]);
42
+ }
43
+ export function decodeUfgLaunchConfig(encoded: Hex): UfgLaunchConfig {
44
+ const config = decodeAbiParameters([{ type: "tuple", components: ufgLaunchConfigComponents }], encoded)[0];
45
+ if (encodeUfgLaunchConfig(config).toLowerCase() !== encoded.toLowerCase()) throw new LifecyclePlanningError("INVALID_UFG_CONFIG", "UFG launch config must use canonical tuple encoding with no extra bytes");
46
+ return config;
47
+ }
48
+ export function hashUfgLaunchConfig(config: UfgLaunchConfig): Hex {
49
+ return keccak256(encodeUfgLaunchConfig(config));
50
+ }
51
+ export function ufgLaunchNonce(principal: Address, nonce: bigint): bigint {
52
+ getAddress(principal);
53
+ if (BigInt(principal) === 0n || nonce < 0n || nonce >= 1n << 96n) throw new LifecyclePlanningError("INVALID_UFG_NONCE", "UFG requires a nonzero principal and a uint96 nonce");
54
+ return BigInt(principal) << 96n | nonce;
55
+ }
56
+
57
+ /** Internal routing guard, also used by canonical progress and receipt verification. */
58
+ export function assertUfgLaunchAccount(plan: LaunchPlanV1, account: Address): void {
59
+ if (plan.chainId !== 4663n || plan.orchestrator.toLowerCase() !== UFG_ORCHESTRATOR_ADDRESS.toLowerCase() || plan.creator.toLowerCase() !== UFG_LAUNCH_PROXY_ADDRESS.toLowerCase() || plan.nonce < 0n || plan.nonce >= 1n << 256n || plan.nonce >> 96n !== BigInt(account) || BigInt(account) === 0n) {
60
+ throw new LifecyclePlanningError("INVALID_UFG_PLAN", "UFG plans require the pinned Robinhood core/proxy and the sender's principal-namespaced nonce");
61
+ }
62
+ }
63
+ export function ufgPlanPrincipal(plan: LaunchPlanV1): Address {
64
+ if (plan.nonce < 0n || plan.nonce >= 1n << 256n) throw new LifecyclePlanningError("INVALID_UFG_PLAN", "UFG nonce must fit uint256");
65
+ const principal = getAddress(`0x${(plan.nonce >> 96n).toString(16).padStart(40, "0")}`);
66
+ assertUfgLaunchAccount(plan, principal);
67
+ return principal;
68
+ }
69
+ export function buildUfgFeeAssetPolicies(token: Address, reserveAssets: readonly Address[]): LifecycleFeeAssetPolicyV2[] {
70
+ validateUfgLaunchConfig({ treasuryShareBps: 10000, exitFeeBps: 0, reserveAssets });
71
+ getAddress(token);
72
+ if (BigInt(token) === 0n || reserveAssets.some((asset) => asset.toLowerCase() === token.toLowerCase())) throw new LifecyclePlanningError("INVALID_UFG_CONFIG", "The launched token must be nonzero and distinct from every reserve");
73
+ return [
74
+ { asset: token, ownerBps: 0, rewardsBps: 0, burnBps: 10000 },
75
+ ...reserveAssets.map((asset) => ({ asset, ownerBps: 10000, rewardsBps: 0, burnBps: 0 })),
76
+ ].sort((a, b) => BigInt(a.asset) < BigInt(b.asset) ? -1 : 1);
77
+ }
@@ -0,0 +1,86 @@
1
+ import { decodeFunctionResult, encodeFunctionData, keccak256, stringToHex, zeroAddress, type Address } 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, type LaunchPlanV1 } from "./schema.js";
8
+ import { LifecyclePlanningError, type BuildLaunchTransactionsOptions, type LifecycleRpcClient, type LifecycleTransaction } 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, type UfgLaunchConfig } from "./ufg-config.js";
10
+
11
+ 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, type UfgLaunchConfig } from "./ufg-config.js";
12
+
13
+ /** Offline proxy-specific admission. Live token/reserve code, registry and transfer checks still require simulation. */
14
+ export function validateUfgLaunchPlan(plan: LaunchPlanV1, config: UfgLaunchConfig, predictedToken: Address): void {
15
+ try {
16
+ ufgPlanPrincipal(plan);
17
+ encodeUfgLaunchConfig(config);
18
+ 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())) throw new Error("UFG requires ERC20/no rewards, zero executor fee, markets and external inventory/buy recipients");
19
+ const expected = buildUfgFeeAssetPolicies(predictedToken, config.reserveAssets);
20
+ if (plan.feeAssets.length !== expected.length || plan.feeAssets.some((policy, index) => {
21
+ const required = expected[index]!;
22
+ return policy.asset.toLowerCase() !== required.asset.toLowerCase() || policy.ownerBps !== required.ownerBps || policy.rewardsBps !== 0 || policy.burnBps !== required.burnBps;
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))) throw new Error("Every reserve must be a market quote and every market quote a reserve");
27
+ const configHash = hashUfgLaunchConfig(config);
28
+ for (const market of plan.markets) {
29
+ if (market.configVersion === 1) {
30
+ const inner = decodeAbyssLifecycleMarketConfig(market.config);
31
+ const profile = getKnownLifecycleProfile({ chainId: plan.chainId, orchestrator: plan.orchestrator, key: inner.profile === 2 ? KnownLifecycleProfile.Abyss2 : KnownLifecycleProfile.Abyss3 });
32
+ 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()) throw new Error("UFG Abyss markets require canonical QUOTE or QUOTE_ORACLE config1 without a tail");
33
+ } else if (market.configVersion === 6) {
34
+ if (!isUfgProfile(market.profileId)) throw new Error("UFG config6 markets require an admitted UFG fixed or dynamic profile");
35
+ const inner = decodePoolBoundV4LifecycleMarketConfig(market.config, 6);
36
+ const adapterId = market.profileId.toLowerCase() === UFG_FIXED_PROFILE_ID ? UFG_FIXED_ADAPTER_ID : UFG_DYNAMIC_ADAPTER_ID;
37
+ 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) throw new Error("Every UFG config6 market requires QuoteOnly, zero LP fee and the identical canonical proxy config tail");
38
+ } else throw new Error("UFG supports only canonical Abyss config1 and UFG pool-bound config6");
39
+ }
40
+ } catch (error) {
41
+ if (error instanceof LifecyclePlanningError && error.code === "INVALID_UFG_PLAN") throw error;
42
+ throw new LifecyclePlanningError("INVALID_UFG_PLAN", error instanceof Error ? error.message : "Invalid UFG launch plan");
43
+ }
44
+ }
45
+
46
+ export type BuildUfgLaunchTransactionsOptions = BuildLaunchTransactionsOptions & { config: UfgLaunchConfig };
47
+ /** Pure unsigned proxy commands; account is the principal encoded in plan.nonce. */
48
+ export function buildUfgLaunchTransactions(options: BuildUfgLaunchTransactionsOptions): LifecycleTransaction[] {
49
+ const { plan, config } = options;
50
+ const principal = ufgPlanPrincipal(plan);
51
+ encodeUfgLaunchConfig(config);
52
+ return buildLaunchTransactions(options).map((transaction) => {
53
+ const data = transaction.kind === "atomic" ? encodeFunctionData({ abi: ufgLaunchProxyV1Abi, functionName: "launchAtomic", args: [plan, config] })
54
+ : transaction.kind === "begin" ? encodeFunctionData({ abi: ufgLaunchProxyV1Abi, functionName: "beginLaunch", args: [plan, LifecycleMode.Staged, config] }) : transaction.data;
55
+ return { ...transaction, from: principal, to: UFG_LAUNCH_PROXY_ADDRESS, data, calldataBytes: (data.length - 2) / 2 };
56
+ });
57
+ }
58
+ export function buildUfgCancelTransaction({ plan, preparedMarkets = 0 }: { plan: LaunchPlanV1; preparedMarkets?: number }): LifecycleTransaction {
59
+ const data = encodeFunctionData({ abi: ufgLaunchProxyV1Abi, functionName: "cancelLaunch", args: [plan] });
60
+ 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 }] };
61
+ }
62
+ /** Exact summed proxy pulls, not escrow allowances. Current allowance/reset discovery belongs to planning. */
63
+ export function buildUfgApprovals(plan: LaunchPlanV1): LifecycleTransaction[] {
64
+ const principal = ufgPlanPrincipal(plan);
65
+ const totals = new Map<string, { asset: Address; amount: bigint }>();
66
+ for (const funding of plan.funding) {
67
+ if (funding.kind === LifecycleFundingKind.NativeWrap || BigInt(funding.inputAsset) === 0n) continue;
68
+ const asset = funding.kind === LifecycleFundingKind.ERC20 ? funding.asset : funding.inputAsset;
69
+ const amount = funding.kind === LifecycleFundingKind.ERC20 ? funding.amount : funding.inputAmount;
70
+ const key = asset.toLowerCase();
71
+ const entry = totals.get(key);
72
+ if (entry === undefined) totals.set(key, { asset, amount }); else entry.amount += amount;
73
+ }
74
+ const transactions = [...totals.values()].map(({ asset, amount }): LifecycleTransaction => {
75
+ const data = encodeFunctionData({ abi: lifecycleErc20Abi, functionName: "approve", args: [UFG_LAUNCH_PROXY_ADDRESS, amount] });
76
+ 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 }] };
77
+ });
78
+ return transactions.map((transaction, index) => ({ ...transaction, dependencies: index === 0 ? [] : [transactions[index - 1]!.id] }));
79
+ }
80
+ /** Read-only upstream treasury lookup. No treasury is represented by undefined, not the zero address. */
81
+ export async function readUfgTreasury(client: LifecycleRpcClient, token: Address): Promise<Address | undefined> {
82
+ const data = encodeFunctionData({ abi: ufgTreasuryFactoryV1Abi, functionName: "treasuryOf", args: [token] });
83
+ const result = await client.request({ method: "eth_call", params: [{ to: UFG_TREASURY_FACTORY_ADDRESS, data }, "latest"] });
84
+ const treasury = decodeFunctionResult({ abi: ufgTreasuryFactoryV1Abi, functionName: "treasuryOf", data: result as `0x${string}` });
85
+ return treasury === zeroAddress ? undefined : treasury;
86
+ }