@whetstone-research/doppler-sdk 1.0.4 → 1.0.6
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 +11 -0
- package/dist/evm/index.cjs +917 -354
- package/dist/evm/index.cjs.map +1 -1
- package/dist/evm/index.d.cts +674 -8
- package/dist/evm/index.d.ts +674 -8
- package/dist/evm/index.js +917 -356
- package/dist/evm/index.js.map +1 -1
- package/package.json +1 -1
package/dist/evm/index.cjs
CHANGED
|
@@ -299,6 +299,14 @@ var ADDRESSES = {
|
|
|
299
299
|
[CHAIN_IDS.MAINNET]: {
|
|
300
300
|
airlock: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.MAINNET].Airlock,
|
|
301
301
|
tokenFactory: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.MAINNET].CloneERC20Factory,
|
|
302
|
+
derc20V2Factory: getGeneratedAddress(
|
|
303
|
+
CHAIN_IDS.MAINNET,
|
|
304
|
+
"CloneDERC20VotesV2Factory"
|
|
305
|
+
),
|
|
306
|
+
derc20V2Implementation: getGeneratedAddress(
|
|
307
|
+
CHAIN_IDS.MAINNET,
|
|
308
|
+
"CloneDERC20VotesV2"
|
|
309
|
+
),
|
|
302
310
|
v3Initializer: ZERO_ADDRESS,
|
|
303
311
|
v3Quoter: ZERO_ADDRESS,
|
|
304
312
|
v4Initializer: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.MAINNET].UniswapV4Initializer,
|
|
@@ -331,6 +339,14 @@ var ADDRESSES = {
|
|
|
331
339
|
[CHAIN_IDS.ETH_SEPOLIA]: {
|
|
332
340
|
airlock: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.ETH_SEPOLIA].Airlock,
|
|
333
341
|
tokenFactory: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.ETH_SEPOLIA].CloneERC20Factory,
|
|
342
|
+
derc20V2Factory: getGeneratedAddress(
|
|
343
|
+
CHAIN_IDS.ETH_SEPOLIA,
|
|
344
|
+
"CloneDERC20VotesV2Factory"
|
|
345
|
+
),
|
|
346
|
+
derc20V2Implementation: getGeneratedAddress(
|
|
347
|
+
CHAIN_IDS.ETH_SEPOLIA,
|
|
348
|
+
"CloneDERC20VotesV2"
|
|
349
|
+
),
|
|
334
350
|
v3Initializer: ZERO_ADDRESS,
|
|
335
351
|
v3Quoter: ZERO_ADDRESS,
|
|
336
352
|
v4Initializer: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.ETH_SEPOLIA].UniswapV4Initializer,
|
|
@@ -361,6 +377,14 @@ var ADDRESSES = {
|
|
|
361
377
|
[CHAIN_IDS.BASE]: {
|
|
362
378
|
airlock: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.BASE].Airlock,
|
|
363
379
|
tokenFactory: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.BASE].TokenFactory80,
|
|
380
|
+
derc20V2Factory: getGeneratedAddress(
|
|
381
|
+
CHAIN_IDS.BASE,
|
|
382
|
+
"CloneDERC20VotesV2Factory"
|
|
383
|
+
),
|
|
384
|
+
derc20V2Implementation: getGeneratedAddress(
|
|
385
|
+
CHAIN_IDS.BASE,
|
|
386
|
+
"CloneDERC20VotesV2"
|
|
387
|
+
),
|
|
364
388
|
v3Initializer: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.BASE].UniswapV3Initializer,
|
|
365
389
|
v3Quoter: "0x3d4e44Eb1374240CE5F1B871ab261CD16335B76a",
|
|
366
390
|
lockableV3Initializer: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.BASE].LockableUniswapV3Initializer,
|
|
@@ -399,6 +423,14 @@ var ADDRESSES = {
|
|
|
399
423
|
[CHAIN_IDS.BASE_SEPOLIA]: {
|
|
400
424
|
airlock: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.BASE_SEPOLIA].Airlock,
|
|
401
425
|
tokenFactory: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.BASE_SEPOLIA].TokenFactory80,
|
|
426
|
+
derc20V2Factory: getGeneratedAddress(
|
|
427
|
+
CHAIN_IDS.BASE_SEPOLIA,
|
|
428
|
+
"CloneDERC20VotesV2Factory"
|
|
429
|
+
),
|
|
430
|
+
derc20V2Implementation: getGeneratedAddress(
|
|
431
|
+
CHAIN_IDS.BASE_SEPOLIA,
|
|
432
|
+
"CloneDERC20VotesV2"
|
|
433
|
+
),
|
|
402
434
|
doppler404Factory: "0xdd8cea2890f1b3498436f19ec8da8fecc2cb7af7",
|
|
403
435
|
v3Initializer: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.BASE_SEPOLIA].UniswapV3Initializer,
|
|
404
436
|
v3Quoter: "0xC5290058841028F1614F3A6F0F5816cAd0df5E27",
|
|
@@ -441,6 +473,14 @@ var ADDRESSES = {
|
|
|
441
473
|
[CHAIN_IDS.INK]: {
|
|
442
474
|
airlock: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.INK].Airlock,
|
|
443
475
|
tokenFactory: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.INK].TokenFactory,
|
|
476
|
+
derc20V2Factory: getGeneratedAddress(
|
|
477
|
+
CHAIN_IDS.INK,
|
|
478
|
+
"CloneDERC20VotesV2Factory"
|
|
479
|
+
),
|
|
480
|
+
derc20V2Implementation: getGeneratedAddress(
|
|
481
|
+
CHAIN_IDS.INK,
|
|
482
|
+
"CloneDERC20VotesV2"
|
|
483
|
+
),
|
|
444
484
|
v3Initializer: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.INK].UniswapV3Initializer,
|
|
445
485
|
v3Quoter: "0x96b572D2d880cf2Fa2563651BD23ADE6f5516652",
|
|
446
486
|
v4Initializer: "0xC99b485499f78995C6F1640dbB1413c57f8BA684",
|
|
@@ -464,6 +504,14 @@ var ADDRESSES = {
|
|
|
464
504
|
[CHAIN_IDS.UNICHAIN]: {
|
|
465
505
|
airlock: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.UNICHAIN].Airlock,
|
|
466
506
|
tokenFactory: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.UNICHAIN].TokenFactory,
|
|
507
|
+
derc20V2Factory: getGeneratedAddress(
|
|
508
|
+
CHAIN_IDS.UNICHAIN,
|
|
509
|
+
"CloneDERC20VotesV2Factory"
|
|
510
|
+
),
|
|
511
|
+
derc20V2Implementation: getGeneratedAddress(
|
|
512
|
+
CHAIN_IDS.UNICHAIN,
|
|
513
|
+
"CloneDERC20VotesV2"
|
|
514
|
+
),
|
|
467
515
|
v3Initializer: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.UNICHAIN].UniswapV3Initializer,
|
|
468
516
|
v3Quoter: "0x385A5cf5F83e99f7BB2852b6A19C3538b9FA7658",
|
|
469
517
|
v4Initializer: "0x2F2BAcd46d3F5c9EE052Ab392b73711dB89129DB",
|
|
@@ -487,6 +535,14 @@ var ADDRESSES = {
|
|
|
487
535
|
[CHAIN_IDS.UNICHAIN_SEPOLIA]: {
|
|
488
536
|
airlock: "0x651ab94B4777e2e4cdf96082d90C65bd947b73A4",
|
|
489
537
|
tokenFactory: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.UNICHAIN_SEPOLIA].TokenFactory,
|
|
538
|
+
derc20V2Factory: getGeneratedAddress(
|
|
539
|
+
CHAIN_IDS.UNICHAIN_SEPOLIA,
|
|
540
|
+
"CloneDERC20VotesV2Factory"
|
|
541
|
+
),
|
|
542
|
+
derc20V2Implementation: getGeneratedAddress(
|
|
543
|
+
CHAIN_IDS.UNICHAIN_SEPOLIA,
|
|
544
|
+
"CloneDERC20VotesV2"
|
|
545
|
+
),
|
|
490
546
|
v3Initializer: "0x7Fb9a622186B4660A5988C223ebb9d3690dD5007",
|
|
491
547
|
v3Quoter: "0x6Dd37329A1A225a6Fca658265D460423DCafBF89",
|
|
492
548
|
v4Initializer: "0x992375478626E67F4e639d3298EbCAaE51C3dF0b",
|
|
@@ -510,6 +566,14 @@ var ADDRESSES = {
|
|
|
510
566
|
[CHAIN_IDS.MONAD_TESTNET]: {
|
|
511
567
|
airlock: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.MONAD_TESTNET].Airlock,
|
|
512
568
|
tokenFactory: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.MONAD_TESTNET].TokenFactory80,
|
|
569
|
+
derc20V2Factory: getGeneratedAddress(
|
|
570
|
+
CHAIN_IDS.MONAD_TESTNET,
|
|
571
|
+
"CloneDERC20VotesV2Factory"
|
|
572
|
+
),
|
|
573
|
+
derc20V2Implementation: getGeneratedAddress(
|
|
574
|
+
CHAIN_IDS.MONAD_TESTNET,
|
|
575
|
+
"CloneDERC20VotesV2"
|
|
576
|
+
),
|
|
513
577
|
v3Initializer: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.MONAD_TESTNET].UniswapV3Initializer,
|
|
514
578
|
v3Quoter: ZERO_ADDRESS,
|
|
515
579
|
v4Initializer: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.MONAD_TESTNET].UniswapV4Initializer,
|
|
@@ -534,6 +598,14 @@ var ADDRESSES = {
|
|
|
534
598
|
[CHAIN_IDS.MONAD_MAINNET]: {
|
|
535
599
|
airlock: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.MONAD_MAINNET].Airlock,
|
|
536
600
|
tokenFactory: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.MONAD_MAINNET].TokenFactory80,
|
|
601
|
+
derc20V2Factory: getGeneratedAddress(
|
|
602
|
+
CHAIN_IDS.MONAD_MAINNET,
|
|
603
|
+
"CloneDERC20VotesV2Factory"
|
|
604
|
+
),
|
|
605
|
+
derc20V2Implementation: getGeneratedAddress(
|
|
606
|
+
CHAIN_IDS.MONAD_MAINNET,
|
|
607
|
+
"CloneDERC20VotesV2"
|
|
608
|
+
),
|
|
537
609
|
v3Initializer: ZERO_ADDRESS,
|
|
538
610
|
v3Quoter: "0x66266174564170519409d8853898f065c719536b",
|
|
539
611
|
v4Initializer: ZERO_ADDRESS,
|
|
@@ -1774,6 +1846,87 @@ var derc20Abi = [
|
|
|
1774
1846
|
]
|
|
1775
1847
|
}
|
|
1776
1848
|
];
|
|
1849
|
+
var derc20V2Abi = [
|
|
1850
|
+
...derc20Abi,
|
|
1851
|
+
{
|
|
1852
|
+
type: "function",
|
|
1853
|
+
name: "computeAvailableVestedAmount",
|
|
1854
|
+
inputs: [
|
|
1855
|
+
{ name: "beneficiary", type: "address", internalType: "address" },
|
|
1856
|
+
{ name: "scheduleId", type: "uint256", internalType: "uint256" }
|
|
1857
|
+
],
|
|
1858
|
+
outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
|
|
1859
|
+
stateMutability: "view"
|
|
1860
|
+
},
|
|
1861
|
+
{
|
|
1862
|
+
type: "function",
|
|
1863
|
+
name: "getScheduleIdsOf",
|
|
1864
|
+
inputs: [{ name: "beneficiary", type: "address", internalType: "address" }],
|
|
1865
|
+
outputs: [{ name: "", type: "uint256[]", internalType: "uint256[]" }],
|
|
1866
|
+
stateMutability: "view"
|
|
1867
|
+
},
|
|
1868
|
+
{
|
|
1869
|
+
type: "function",
|
|
1870
|
+
name: "release",
|
|
1871
|
+
inputs: [{ name: "scheduleId", type: "uint256", internalType: "uint256" }],
|
|
1872
|
+
outputs: [],
|
|
1873
|
+
stateMutability: "nonpayable"
|
|
1874
|
+
},
|
|
1875
|
+
{
|
|
1876
|
+
type: "function",
|
|
1877
|
+
name: "releaseFor",
|
|
1878
|
+
inputs: [
|
|
1879
|
+
{ name: "beneficiary", type: "address", internalType: "address" },
|
|
1880
|
+
{ name: "scheduleId", type: "uint256", internalType: "uint256" }
|
|
1881
|
+
],
|
|
1882
|
+
outputs: [],
|
|
1883
|
+
stateMutability: "nonpayable"
|
|
1884
|
+
},
|
|
1885
|
+
{
|
|
1886
|
+
type: "function",
|
|
1887
|
+
name: "releaseFor",
|
|
1888
|
+
inputs: [{ name: "beneficiary", type: "address", internalType: "address" }],
|
|
1889
|
+
outputs: [],
|
|
1890
|
+
stateMutability: "nonpayable"
|
|
1891
|
+
},
|
|
1892
|
+
{
|
|
1893
|
+
type: "function",
|
|
1894
|
+
name: "totalAllocatedOf",
|
|
1895
|
+
inputs: [{ name: "beneficiary", type: "address", internalType: "address" }],
|
|
1896
|
+
outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
|
|
1897
|
+
stateMutability: "view"
|
|
1898
|
+
},
|
|
1899
|
+
{
|
|
1900
|
+
type: "function",
|
|
1901
|
+
name: "vestingOf",
|
|
1902
|
+
inputs: [
|
|
1903
|
+
{ name: "beneficiary", type: "address", internalType: "address" },
|
|
1904
|
+
{ name: "scheduleId", type: "uint256", internalType: "uint256" }
|
|
1905
|
+
],
|
|
1906
|
+
outputs: [
|
|
1907
|
+
{ name: "totalAmount", type: "uint256", internalType: "uint256" },
|
|
1908
|
+
{ name: "releasedAmount", type: "uint256", internalType: "uint256" }
|
|
1909
|
+
],
|
|
1910
|
+
stateMutability: "view"
|
|
1911
|
+
},
|
|
1912
|
+
{
|
|
1913
|
+
type: "function",
|
|
1914
|
+
name: "vestingScheduleCount",
|
|
1915
|
+
inputs: [],
|
|
1916
|
+
outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
|
|
1917
|
+
stateMutability: "view"
|
|
1918
|
+
},
|
|
1919
|
+
{
|
|
1920
|
+
type: "function",
|
|
1921
|
+
name: "vestingSchedules",
|
|
1922
|
+
inputs: [{ name: "", type: "uint256", internalType: "uint256" }],
|
|
1923
|
+
outputs: [
|
|
1924
|
+
{ name: "cliff", type: "uint64", internalType: "uint64" },
|
|
1925
|
+
{ name: "duration", type: "uint64", internalType: "uint64" }
|
|
1926
|
+
],
|
|
1927
|
+
stateMutability: "view"
|
|
1928
|
+
}
|
|
1929
|
+
];
|
|
1777
1930
|
var uniswapV4InitializerAbi = [
|
|
1778
1931
|
{
|
|
1779
1932
|
type: "function",
|
|
@@ -4319,6 +4472,22 @@ var STANDARD_TOKEN_DATA_ABI = [
|
|
|
4319
4472
|
{ type: "uint256[]" },
|
|
4320
4473
|
{ type: "string" }
|
|
4321
4474
|
];
|
|
4475
|
+
var STANDARD_TOKEN_V2_DATA_ABI = [
|
|
4476
|
+
{ type: "string" },
|
|
4477
|
+
{ type: "string" },
|
|
4478
|
+
{ type: "uint256" },
|
|
4479
|
+
{
|
|
4480
|
+
type: "tuple[]",
|
|
4481
|
+
components: [
|
|
4482
|
+
{ type: "uint64", name: "cliff" },
|
|
4483
|
+
{ type: "uint64", name: "duration" }
|
|
4484
|
+
]
|
|
4485
|
+
},
|
|
4486
|
+
{ type: "address[]" },
|
|
4487
|
+
{ type: "uint256[]" },
|
|
4488
|
+
{ type: "uint256[]" },
|
|
4489
|
+
{ type: "string" }
|
|
4490
|
+
];
|
|
4322
4491
|
var DOPPLER404_TOKEN_DATA_ABI = [
|
|
4323
4492
|
{ type: "string" },
|
|
4324
4493
|
{ type: "string" },
|
|
@@ -4376,6 +4545,13 @@ function computeCreate2AddressFast(buffer) {
|
|
|
4376
4545
|
const hash = viem.keccak256(bytesToHex(buffer));
|
|
4377
4546
|
return "0x" + hash.slice(-40).toLowerCase();
|
|
4378
4547
|
}
|
|
4548
|
+
function computeSoladyCloneInitCodeHash(implementation) {
|
|
4549
|
+
return viem.keccak256(
|
|
4550
|
+
`0x602c3d8160093d39f33d3d3d3d363d3d37363d73${implementation.slice(
|
|
4551
|
+
2
|
|
4552
|
+
)}5af43d3d93803e602a57fd5bf3`
|
|
4553
|
+
);
|
|
4554
|
+
}
|
|
4379
4555
|
function buildTokenInitHash(params) {
|
|
4380
4556
|
const {
|
|
4381
4557
|
variant,
|
|
@@ -4384,7 +4560,8 @@ function buildTokenInitHash(params) {
|
|
|
4384
4560
|
initialSupply,
|
|
4385
4561
|
recipient,
|
|
4386
4562
|
owner,
|
|
4387
|
-
customBytecode
|
|
4563
|
+
customBytecode,
|
|
4564
|
+
v2Implementation
|
|
4388
4565
|
} = params;
|
|
4389
4566
|
if (variant === "doppler404") {
|
|
4390
4567
|
const [name2, symbol2, baseURI] = viem.decodeAbiParameters(
|
|
@@ -4409,6 +4586,15 @@ function buildTokenInitHash(params) {
|
|
|
4409
4586
|
)
|
|
4410
4587
|
);
|
|
4411
4588
|
}
|
|
4589
|
+
if (variant === "standard-v2") {
|
|
4590
|
+
viem.decodeAbiParameters(STANDARD_TOKEN_V2_DATA_ABI, tokenData);
|
|
4591
|
+
if (!v2Implementation) {
|
|
4592
|
+
throw new Error(
|
|
4593
|
+
"TokenAddressMiner: v2Implementation is required for standard-v2 tokens"
|
|
4594
|
+
);
|
|
4595
|
+
}
|
|
4596
|
+
return computeSoladyCloneInitCodeHash(v2Implementation);
|
|
4597
|
+
}
|
|
4412
4598
|
const [
|
|
4413
4599
|
name,
|
|
4414
4600
|
symbol,
|
|
@@ -4489,7 +4675,8 @@ function mineTokenAddress(params) {
|
|
|
4489
4675
|
initialSupply,
|
|
4490
4676
|
recipient,
|
|
4491
4677
|
owner,
|
|
4492
|
-
customBytecode
|
|
4678
|
+
customBytecode,
|
|
4679
|
+
v2Implementation: params.v2Implementation
|
|
4493
4680
|
});
|
|
4494
4681
|
const hookConfig = hook ? {
|
|
4495
4682
|
deployer: hook.deployer,
|
|
@@ -5094,6 +5281,8 @@ var erc20BalanceOfAbi = [
|
|
|
5094
5281
|
}
|
|
5095
5282
|
];
|
|
5096
5283
|
var TOKEN_FACTORY_80_ADDRESS2 = "0xf0b5141dd9096254b2ca624dff26024f46087229";
|
|
5284
|
+
var DERC20_V2_MIN_VESTING_DURATION = 24 * 60 * 60;
|
|
5285
|
+
var MAX_UINT64 = (1n << 64n) - 1n;
|
|
5097
5286
|
var DopplerFactory = class {
|
|
5098
5287
|
publicClient;
|
|
5099
5288
|
walletClient;
|
|
@@ -5105,6 +5294,285 @@ var DopplerFactory = class {
|
|
|
5105
5294
|
this.walletClient = walletClient;
|
|
5106
5295
|
this.chainId = chainId;
|
|
5107
5296
|
}
|
|
5297
|
+
hasCustomV2Schedules(vesting) {
|
|
5298
|
+
return (vesting?.schedules?.length ?? 0) > 0 || (vesting?.scheduleIds?.length ?? 0) > 0;
|
|
5299
|
+
}
|
|
5300
|
+
usesDerc20V2Vesting(vesting) {
|
|
5301
|
+
if (!vesting) {
|
|
5302
|
+
return false;
|
|
5303
|
+
}
|
|
5304
|
+
return this.hasCustomV2Schedules(vesting) || (vesting.cliffDuration ?? 0) > 0;
|
|
5305
|
+
}
|
|
5306
|
+
resolveVestingAllocations(args) {
|
|
5307
|
+
if (!args.vesting) {
|
|
5308
|
+
return { recipients: [], amounts: [] };
|
|
5309
|
+
}
|
|
5310
|
+
if (args.vesting.recipients && args.vesting.amounts) {
|
|
5311
|
+
return {
|
|
5312
|
+
recipients: args.vesting.recipients,
|
|
5313
|
+
amounts: args.vesting.amounts
|
|
5314
|
+
};
|
|
5315
|
+
}
|
|
5316
|
+
return {
|
|
5317
|
+
recipients: [args.userAddress],
|
|
5318
|
+
amounts: [args.sale.initialSupply - args.sale.numTokensToSell]
|
|
5319
|
+
};
|
|
5320
|
+
}
|
|
5321
|
+
normalizeV2ScheduleId(scheduleId, label) {
|
|
5322
|
+
if (!Number.isFinite(scheduleId) || !Number.isInteger(scheduleId)) {
|
|
5323
|
+
throw new Error(`${label} must be an integer`);
|
|
5324
|
+
}
|
|
5325
|
+
if (!Number.isSafeInteger(scheduleId)) {
|
|
5326
|
+
throw new Error(`${label} must be a safe integer`);
|
|
5327
|
+
}
|
|
5328
|
+
if (scheduleId < 0) {
|
|
5329
|
+
throw new Error(`${label} cannot be negative`);
|
|
5330
|
+
}
|
|
5331
|
+
return BigInt(scheduleId);
|
|
5332
|
+
}
|
|
5333
|
+
validateUint64LikeNumber(value, fieldPath, options = {}) {
|
|
5334
|
+
const { allowZero = true } = options;
|
|
5335
|
+
if (!Number.isFinite(value) || !Number.isInteger(value)) {
|
|
5336
|
+
throw new Error(`${fieldPath} must be a finite integer`);
|
|
5337
|
+
}
|
|
5338
|
+
if (!Number.isSafeInteger(value)) {
|
|
5339
|
+
throw new Error(`${fieldPath} must be a safe integer`);
|
|
5340
|
+
}
|
|
5341
|
+
if (value < 0) {
|
|
5342
|
+
throw new Error(`${fieldPath} cannot be negative`);
|
|
5343
|
+
}
|
|
5344
|
+
if (!allowZero && value === 0) {
|
|
5345
|
+
throw new Error(`${fieldPath} must be greater than zero`);
|
|
5346
|
+
}
|
|
5347
|
+
if (BigInt(value) > MAX_UINT64) {
|
|
5348
|
+
throw new Error(`${fieldPath} must fit in uint64`);
|
|
5349
|
+
}
|
|
5350
|
+
}
|
|
5351
|
+
resolveV2VestingSchedules(args) {
|
|
5352
|
+
if (!args.vesting) {
|
|
5353
|
+
return { schedules: [], scheduleIds: [] };
|
|
5354
|
+
}
|
|
5355
|
+
if (!this.hasCustomV2Schedules(args.vesting)) {
|
|
5356
|
+
return {
|
|
5357
|
+
schedules: [
|
|
5358
|
+
{
|
|
5359
|
+
cliff: BigInt(args.vesting.cliffDuration ?? 0),
|
|
5360
|
+
duration: BigInt(args.vesting.duration ?? 0)
|
|
5361
|
+
}
|
|
5362
|
+
],
|
|
5363
|
+
scheduleIds: Array.from({ length: args.recipientCount }, () => 0n)
|
|
5364
|
+
};
|
|
5365
|
+
}
|
|
5366
|
+
const schedules = args.vesting.schedules?.map((schedule) => ({
|
|
5367
|
+
cliff: BigInt(schedule.cliffDuration ?? 0),
|
|
5368
|
+
duration: BigInt(schedule.duration ?? 0)
|
|
5369
|
+
})) ?? [];
|
|
5370
|
+
const explicitScheduleIds = args.vesting.scheduleIds;
|
|
5371
|
+
if (explicitScheduleIds && explicitScheduleIds.length > 0) {
|
|
5372
|
+
return {
|
|
5373
|
+
schedules,
|
|
5374
|
+
scheduleIds: explicitScheduleIds.map(
|
|
5375
|
+
(scheduleId, index) => this.normalizeV2ScheduleId(
|
|
5376
|
+
scheduleId,
|
|
5377
|
+
`Vesting scheduleIds[${index}]`
|
|
5378
|
+
)
|
|
5379
|
+
)
|
|
5380
|
+
};
|
|
5381
|
+
}
|
|
5382
|
+
if (schedules.length === 1) {
|
|
5383
|
+
return {
|
|
5384
|
+
schedules,
|
|
5385
|
+
scheduleIds: Array.from({ length: args.recipientCount }, () => 0n)
|
|
5386
|
+
};
|
|
5387
|
+
}
|
|
5388
|
+
if (schedules.length === args.recipientCount) {
|
|
5389
|
+
return {
|
|
5390
|
+
schedules,
|
|
5391
|
+
scheduleIds: schedules.map((_, index) => BigInt(index))
|
|
5392
|
+
};
|
|
5393
|
+
}
|
|
5394
|
+
throw new Error(
|
|
5395
|
+
"Vesting schedules must either contain exactly one shared schedule or one schedule per recipient when scheduleIds are omitted"
|
|
5396
|
+
);
|
|
5397
|
+
}
|
|
5398
|
+
resolveStandardTokenFactoryMode(args) {
|
|
5399
|
+
if (this.usesDerc20V2Vesting(args.vesting)) {
|
|
5400
|
+
return "v2";
|
|
5401
|
+
}
|
|
5402
|
+
const v2Factory = args.addresses.derc20V2Factory;
|
|
5403
|
+
if (v2Factory && args.tokenFactory.toLowerCase() === v2Factory.toLowerCase()) {
|
|
5404
|
+
return "v2";
|
|
5405
|
+
}
|
|
5406
|
+
return "legacy";
|
|
5407
|
+
}
|
|
5408
|
+
assertStandardTokenFactoryCompatibility(args) {
|
|
5409
|
+
if (this.isDoppler404Token(args.token) || !this.usesDerc20V2Vesting(args.vesting)) {
|
|
5410
|
+
return;
|
|
5411
|
+
}
|
|
5412
|
+
const v2Factory = args.addresses.derc20V2Factory;
|
|
5413
|
+
if (!v2Factory || v2Factory === ZERO_ADDRESS2) {
|
|
5414
|
+
throw new Error(
|
|
5415
|
+
"Cliff vesting requires the DERC20 V2 factory, but no V2 factory is configured for this chain."
|
|
5416
|
+
);
|
|
5417
|
+
}
|
|
5418
|
+
if (args.tokenFactory.toLowerCase() !== v2Factory.toLowerCase()) {
|
|
5419
|
+
throw new Error(
|
|
5420
|
+
"Cliff vesting requires the DERC20 V2 factory. Remove the tokenFactory override or point it at the chain DERC20 V2 factory."
|
|
5421
|
+
);
|
|
5422
|
+
}
|
|
5423
|
+
}
|
|
5424
|
+
buildStandardTokenFactoryData(args) {
|
|
5425
|
+
const { recipients, amounts } = this.resolveVestingAllocations(args);
|
|
5426
|
+
const yearlyMintRate = args.token.yearlyMintRate ?? DEFAULT_V4_YEARLY_MINT_RATE;
|
|
5427
|
+
const mode = this.resolveStandardTokenFactoryMode({
|
|
5428
|
+
vesting: args.vesting,
|
|
5429
|
+
tokenFactory: args.tokenFactory,
|
|
5430
|
+
addresses: args.addresses
|
|
5431
|
+
});
|
|
5432
|
+
if (mode === "v2") {
|
|
5433
|
+
const implementation = args.addresses.derc20V2Implementation;
|
|
5434
|
+
if (!implementation || implementation === ZERO_ADDRESS2) {
|
|
5435
|
+
throw new Error(
|
|
5436
|
+
"DERC20 V2 implementation address not configured for this chain."
|
|
5437
|
+
);
|
|
5438
|
+
}
|
|
5439
|
+
const { schedules, scheduleIds } = this.resolveV2VestingSchedules({
|
|
5440
|
+
vesting: args.vesting,
|
|
5441
|
+
recipientCount: recipients.length
|
|
5442
|
+
});
|
|
5443
|
+
return {
|
|
5444
|
+
kind: "v2",
|
|
5445
|
+
name: args.token.name,
|
|
5446
|
+
symbol: args.token.symbol,
|
|
5447
|
+
initialSupply: args.sale.initialSupply,
|
|
5448
|
+
airlock: args.airlock,
|
|
5449
|
+
yearlyMintRate,
|
|
5450
|
+
schedules,
|
|
5451
|
+
beneficiaries: recipients,
|
|
5452
|
+
scheduleIds,
|
|
5453
|
+
amounts,
|
|
5454
|
+
tokenURI: args.token.tokenURI,
|
|
5455
|
+
implementation
|
|
5456
|
+
};
|
|
5457
|
+
}
|
|
5458
|
+
return {
|
|
5459
|
+
kind: "legacy",
|
|
5460
|
+
name: args.token.name,
|
|
5461
|
+
symbol: args.token.symbol,
|
|
5462
|
+
initialSupply: args.sale.initialSupply,
|
|
5463
|
+
airlock: args.airlock,
|
|
5464
|
+
yearlyMintRate,
|
|
5465
|
+
vestingDuration: BigInt(args.vesting?.duration ?? 0),
|
|
5466
|
+
recipients,
|
|
5467
|
+
amounts,
|
|
5468
|
+
tokenURI: args.token.tokenURI
|
|
5469
|
+
};
|
|
5470
|
+
}
|
|
5471
|
+
encodeStandardTokenFactoryData(tokenFactoryData) {
|
|
5472
|
+
if (tokenFactoryData.kind === "v2") {
|
|
5473
|
+
return viem.encodeAbiParameters(
|
|
5474
|
+
[
|
|
5475
|
+
{ type: "string" },
|
|
5476
|
+
{ type: "string" },
|
|
5477
|
+
{ type: "uint256" },
|
|
5478
|
+
{
|
|
5479
|
+
type: "tuple[]",
|
|
5480
|
+
components: [
|
|
5481
|
+
{ type: "uint64", name: "cliff" },
|
|
5482
|
+
{ type: "uint64", name: "duration" }
|
|
5483
|
+
]
|
|
5484
|
+
},
|
|
5485
|
+
{ type: "address[]" },
|
|
5486
|
+
{ type: "uint256[]" },
|
|
5487
|
+
{ type: "uint256[]" },
|
|
5488
|
+
{ type: "string" }
|
|
5489
|
+
],
|
|
5490
|
+
[
|
|
5491
|
+
tokenFactoryData.name,
|
|
5492
|
+
tokenFactoryData.symbol,
|
|
5493
|
+
tokenFactoryData.yearlyMintRate,
|
|
5494
|
+
tokenFactoryData.schedules.map((schedule) => ({
|
|
5495
|
+
cliff: schedule.cliff,
|
|
5496
|
+
duration: schedule.duration
|
|
5497
|
+
})),
|
|
5498
|
+
tokenFactoryData.beneficiaries,
|
|
5499
|
+
tokenFactoryData.scheduleIds,
|
|
5500
|
+
tokenFactoryData.amounts,
|
|
5501
|
+
tokenFactoryData.tokenURI
|
|
5502
|
+
]
|
|
5503
|
+
);
|
|
5504
|
+
}
|
|
5505
|
+
return viem.encodeAbiParameters(
|
|
5506
|
+
[
|
|
5507
|
+
{ type: "string" },
|
|
5508
|
+
{ type: "string" },
|
|
5509
|
+
{ type: "uint256" },
|
|
5510
|
+
{ type: "uint256" },
|
|
5511
|
+
{ type: "address[]" },
|
|
5512
|
+
{ type: "uint256[]" },
|
|
5513
|
+
{ type: "string" }
|
|
5514
|
+
],
|
|
5515
|
+
[
|
|
5516
|
+
tokenFactoryData.name,
|
|
5517
|
+
tokenFactoryData.symbol,
|
|
5518
|
+
tokenFactoryData.yearlyMintRate,
|
|
5519
|
+
tokenFactoryData.vestingDuration,
|
|
5520
|
+
tokenFactoryData.recipients,
|
|
5521
|
+
tokenFactoryData.amounts,
|
|
5522
|
+
tokenFactoryData.tokenURI
|
|
5523
|
+
]
|
|
5524
|
+
);
|
|
5525
|
+
}
|
|
5526
|
+
computeSoladyCloneInitCodeHash(implementation) {
|
|
5527
|
+
return viem.keccak256(
|
|
5528
|
+
`0x602c3d8160093d39f33d3d3d3d363d3d37363d73${implementation.slice(
|
|
5529
|
+
2
|
|
5530
|
+
)}5af43d3d93803e602a57fd5bf3`
|
|
5531
|
+
);
|
|
5532
|
+
}
|
|
5533
|
+
computeStandardTokenInitHash(tokenFactoryData, tokenFactory) {
|
|
5534
|
+
if (tokenFactoryData.kind === "v2") {
|
|
5535
|
+
return this.computeSoladyCloneInitCodeHash(
|
|
5536
|
+
tokenFactoryData.implementation
|
|
5537
|
+
);
|
|
5538
|
+
}
|
|
5539
|
+
const initData = viem.encodeAbiParameters(
|
|
5540
|
+
[
|
|
5541
|
+
{ type: "string" },
|
|
5542
|
+
{ type: "string" },
|
|
5543
|
+
{ type: "uint256" },
|
|
5544
|
+
{ type: "address" },
|
|
5545
|
+
{ type: "address" },
|
|
5546
|
+
{ type: "uint256" },
|
|
5547
|
+
{ type: "uint256" },
|
|
5548
|
+
{ type: "address[]" },
|
|
5549
|
+
{ type: "uint256[]" },
|
|
5550
|
+
{ type: "string" }
|
|
5551
|
+
],
|
|
5552
|
+
[
|
|
5553
|
+
tokenFactoryData.name,
|
|
5554
|
+
tokenFactoryData.symbol,
|
|
5555
|
+
tokenFactoryData.initialSupply,
|
|
5556
|
+
tokenFactoryData.airlock,
|
|
5557
|
+
tokenFactoryData.airlock,
|
|
5558
|
+
tokenFactoryData.yearlyMintRate,
|
|
5559
|
+
tokenFactoryData.vestingDuration,
|
|
5560
|
+
tokenFactoryData.recipients,
|
|
5561
|
+
tokenFactoryData.amounts,
|
|
5562
|
+
tokenFactoryData.tokenURI
|
|
5563
|
+
]
|
|
5564
|
+
);
|
|
5565
|
+
const isTokenFactory802 = tokenFactory.toLowerCase() === TOKEN_FACTORY_80_ADDRESS2;
|
|
5566
|
+
return viem.keccak256(
|
|
5567
|
+
viem.encodePacked(
|
|
5568
|
+
["bytes", "bytes"],
|
|
5569
|
+
[
|
|
5570
|
+
isTokenFactory802 ? derc2080_default : derc20_default,
|
|
5571
|
+
initData
|
|
5572
|
+
]
|
|
5573
|
+
)
|
|
5574
|
+
);
|
|
5575
|
+
}
|
|
5108
5576
|
/**
|
|
5109
5577
|
* Set a custom migration data encoder function
|
|
5110
5578
|
* @param encoder Custom function to encode migration data
|
|
@@ -5189,6 +5657,18 @@ var DopplerFactory = class {
|
|
|
5189
5657
|
numeraire: params.sale.numeraire,
|
|
5190
5658
|
overrides: params.modules
|
|
5191
5659
|
});
|
|
5660
|
+
const resolvedTokenFactory = params.modules?.tokenFactory ?? (this.isDoppler404Token(params.token) ? addresses.doppler404Factory : this.usesDerc20V2Vesting(params.vesting) ? addresses.derc20V2Factory : addresses.tokenFactory);
|
|
5661
|
+
if (!resolvedTokenFactory || resolvedTokenFactory === ZERO_ADDRESS2) {
|
|
5662
|
+
throw new Error(
|
|
5663
|
+
"Token factory address not configured. Provide an explicit address via builder.withTokenFactory(...) or ensure chain config includes a valid factory."
|
|
5664
|
+
);
|
|
5665
|
+
}
|
|
5666
|
+
this.assertStandardTokenFactoryCompatibility({
|
|
5667
|
+
token: params.token,
|
|
5668
|
+
vesting: params.vesting,
|
|
5669
|
+
tokenFactory: resolvedTokenFactory,
|
|
5670
|
+
addresses
|
|
5671
|
+
});
|
|
5192
5672
|
let tokenFactoryData;
|
|
5193
5673
|
if (this.isDoppler404Token(params.token)) {
|
|
5194
5674
|
const token404 = params.token;
|
|
@@ -5204,41 +5684,17 @@ var DopplerFactory = class {
|
|
|
5204
5684
|
[params.token.name, params.token.symbol, baseURI, unit]
|
|
5205
5685
|
);
|
|
5206
5686
|
} else {
|
|
5207
|
-
const
|
|
5208
|
-
|
|
5209
|
-
|
|
5210
|
-
|
|
5211
|
-
|
|
5212
|
-
|
|
5213
|
-
|
|
5214
|
-
|
|
5215
|
-
|
|
5216
|
-
|
|
5217
|
-
|
|
5218
|
-
vestingAmounts = [
|
|
5219
|
-
params.sale.initialSupply - params.sale.numTokensToSell
|
|
5220
|
-
];
|
|
5221
|
-
}
|
|
5222
|
-
}
|
|
5223
|
-
tokenFactoryData = viem.encodeAbiParameters(
|
|
5224
|
-
[
|
|
5225
|
-
{ type: "string" },
|
|
5226
|
-
{ type: "string" },
|
|
5227
|
-
{ type: "uint256" },
|
|
5228
|
-
{ type: "uint256" },
|
|
5229
|
-
{ type: "address[]" },
|
|
5230
|
-
{ type: "uint256[]" },
|
|
5231
|
-
{ type: "string" }
|
|
5232
|
-
],
|
|
5233
|
-
[
|
|
5234
|
-
tokenStd.name,
|
|
5235
|
-
tokenStd.symbol,
|
|
5236
|
-
yearlyMintRate,
|
|
5237
|
-
BigInt(vestingDuration),
|
|
5238
|
-
vestingRecipients,
|
|
5239
|
-
vestingAmounts,
|
|
5240
|
-
tokenStd.tokenURI
|
|
5241
|
-
]
|
|
5687
|
+
const standardTokenFactoryData = this.buildStandardTokenFactoryData({
|
|
5688
|
+
token: params.token,
|
|
5689
|
+
sale: params.sale,
|
|
5690
|
+
vesting: params.vesting,
|
|
5691
|
+
userAddress: params.userAddress,
|
|
5692
|
+
airlock: params.modules?.airlock ?? addresses.airlock,
|
|
5693
|
+
tokenFactory: resolvedTokenFactory,
|
|
5694
|
+
addresses
|
|
5695
|
+
});
|
|
5696
|
+
tokenFactoryData = this.encodeStandardTokenFactoryData(
|
|
5697
|
+
standardTokenFactoryData
|
|
5242
5698
|
);
|
|
5243
5699
|
}
|
|
5244
5700
|
const governanceFactoryData = (() => {
|
|
@@ -5293,12 +5749,6 @@ var DopplerFactory = class {
|
|
|
5293
5749
|
}
|
|
5294
5750
|
return resolved;
|
|
5295
5751
|
})();
|
|
5296
|
-
const resolvedTokenFactory = params.modules?.tokenFactory ?? (this.isDoppler404Token(params.token) ? addresses.doppler404Factory : addresses.tokenFactory);
|
|
5297
|
-
if (!resolvedTokenFactory || resolvedTokenFactory === ZERO_ADDRESS2) {
|
|
5298
|
-
throw new Error(
|
|
5299
|
-
"Token factory address not configured. Provide an explicit address via builder.withTokenFactory(...) or ensure chain config includes a valid factory."
|
|
5300
|
-
);
|
|
5301
|
-
}
|
|
5302
5752
|
const baseCreateParams = {
|
|
5303
5753
|
initialSupply: params.sale.initialSupply,
|
|
5304
5754
|
numTokensToSell: params.sale.numTokensToSell,
|
|
@@ -5584,7 +6034,18 @@ var DopplerFactory = class {
|
|
|
5584
6034
|
);
|
|
5585
6035
|
}
|
|
5586
6036
|
}
|
|
5587
|
-
const
|
|
6037
|
+
const resolvedTokenFactoryDyn = params.modules?.tokenFactory ?? (this.isDoppler404Token(params.token) ? addresses.doppler404Factory : this.usesDerc20V2Vesting(params.vesting) ? addresses.derc20V2Factory : addresses.tokenFactory);
|
|
6038
|
+
if (!resolvedTokenFactoryDyn || resolvedTokenFactoryDyn === ZERO_ADDRESS2) {
|
|
6039
|
+
throw new Error(
|
|
6040
|
+
"Token factory address not configured. Provide an explicit address via builder.withTokenFactory(...) or ensure chain config includes a valid factory."
|
|
6041
|
+
);
|
|
6042
|
+
}
|
|
6043
|
+
this.assertStandardTokenFactoryCompatibility({
|
|
6044
|
+
token: params.token,
|
|
6045
|
+
vesting: params.vesting,
|
|
6046
|
+
tokenFactory: resolvedTokenFactoryDyn,
|
|
6047
|
+
addresses
|
|
6048
|
+
});
|
|
5588
6049
|
const tokenFactoryData = this.isDoppler404Token(params.token) ? (() => {
|
|
5589
6050
|
const t = params.token;
|
|
5590
6051
|
return {
|
|
@@ -5593,39 +6054,15 @@ var DopplerFactory = class {
|
|
|
5593
6054
|
baseURI: t.baseURI,
|
|
5594
6055
|
unit: t.unit !== void 0 ? BigInt(t.unit) : 1000n
|
|
5595
6056
|
};
|
|
5596
|
-
})() : (
|
|
5597
|
-
|
|
5598
|
-
|
|
5599
|
-
|
|
5600
|
-
|
|
5601
|
-
|
|
5602
|
-
|
|
5603
|
-
|
|
5604
|
-
|
|
5605
|
-
vestingRecipients = [params.userAddress];
|
|
5606
|
-
vestingAmounts = [
|
|
5607
|
-
params.sale.initialSupply - params.sale.numTokensToSell
|
|
5608
|
-
];
|
|
5609
|
-
}
|
|
5610
|
-
}
|
|
5611
|
-
return {
|
|
5612
|
-
name: t.name,
|
|
5613
|
-
symbol: t.symbol,
|
|
5614
|
-
initialSupply: params.sale.initialSupply,
|
|
5615
|
-
airlock: addresses.airlock,
|
|
5616
|
-
yearlyMintRate: t.yearlyMintRate ?? DEFAULT_V4_YEARLY_MINT_RATE,
|
|
5617
|
-
vestingDuration: BigInt(vestingDuration),
|
|
5618
|
-
recipients: vestingRecipients,
|
|
5619
|
-
amounts: vestingAmounts,
|
|
5620
|
-
tokenURI: t.tokenURI
|
|
5621
|
-
};
|
|
5622
|
-
})();
|
|
5623
|
-
const resolvedTokenFactoryDyn = params.modules?.tokenFactory ?? (this.isDoppler404Token(params.token) ? addresses.doppler404Factory : addresses.tokenFactory);
|
|
5624
|
-
if (!resolvedTokenFactoryDyn || resolvedTokenFactoryDyn === ZERO_ADDRESS2) {
|
|
5625
|
-
throw new Error(
|
|
5626
|
-
"Token factory address not configured. Provide an explicit address via builder.withTokenFactory(...) or ensure chain config includes a valid factory."
|
|
5627
|
-
);
|
|
5628
|
-
}
|
|
6057
|
+
})() : this.buildStandardTokenFactoryData({
|
|
6058
|
+
token: params.token,
|
|
6059
|
+
sale: params.sale,
|
|
6060
|
+
vesting: params.vesting,
|
|
6061
|
+
userAddress: params.userAddress,
|
|
6062
|
+
airlock: params.modules?.airlock ?? addresses.airlock,
|
|
6063
|
+
tokenFactory: resolvedTokenFactoryDyn,
|
|
6064
|
+
addresses
|
|
6065
|
+
});
|
|
5629
6066
|
const [
|
|
5630
6067
|
salt,
|
|
5631
6068
|
hookAddress,
|
|
@@ -5952,7 +6389,18 @@ var DopplerFactory = class {
|
|
|
5952
6389
|
);
|
|
5953
6390
|
}
|
|
5954
6391
|
}
|
|
5955
|
-
const
|
|
6392
|
+
const resolvedTokenFactory = params.modules?.tokenFactory ?? (this.isDoppler404Token(params.token) ? addresses.doppler404Factory : this.usesDerc20V2Vesting(params.vesting) ? addresses.derc20V2Factory : addresses.tokenFactory);
|
|
6393
|
+
if (!resolvedTokenFactory || resolvedTokenFactory === ZERO_ADDRESS2) {
|
|
6394
|
+
throw new Error(
|
|
6395
|
+
"Token factory address not configured. Provide an explicit address via builder.withTokenFactory(...) or ensure chain config includes a valid factory."
|
|
6396
|
+
);
|
|
6397
|
+
}
|
|
6398
|
+
this.assertStandardTokenFactoryCompatibility({
|
|
6399
|
+
token: params.token,
|
|
6400
|
+
vesting: params.vesting,
|
|
6401
|
+
tokenFactory: resolvedTokenFactory,
|
|
6402
|
+
addresses
|
|
6403
|
+
});
|
|
5956
6404
|
const tokenFactoryData = this.isDoppler404Token(params.token) ? (() => {
|
|
5957
6405
|
const t = params.token;
|
|
5958
6406
|
return {
|
|
@@ -5961,39 +6409,15 @@ var DopplerFactory = class {
|
|
|
5961
6409
|
baseURI: t.baseURI,
|
|
5962
6410
|
unit: t.unit !== void 0 ? BigInt(t.unit) : 1000n
|
|
5963
6411
|
};
|
|
5964
|
-
})() : (
|
|
5965
|
-
|
|
5966
|
-
|
|
5967
|
-
|
|
5968
|
-
|
|
5969
|
-
|
|
5970
|
-
|
|
5971
|
-
|
|
5972
|
-
|
|
5973
|
-
vestingRecipients = [params.userAddress];
|
|
5974
|
-
vestingAmounts = [
|
|
5975
|
-
params.sale.initialSupply - params.sale.numTokensToSell
|
|
5976
|
-
];
|
|
5977
|
-
}
|
|
5978
|
-
}
|
|
5979
|
-
return {
|
|
5980
|
-
name: t.name,
|
|
5981
|
-
symbol: t.symbol,
|
|
5982
|
-
initialSupply: params.sale.initialSupply,
|
|
5983
|
-
airlock: params.modules?.airlock ?? addresses.airlock,
|
|
5984
|
-
yearlyMintRate: t.yearlyMintRate ?? DEFAULT_V4_YEARLY_MINT_RATE,
|
|
5985
|
-
vestingDuration: BigInt(vestingDuration),
|
|
5986
|
-
recipients: vestingRecipients,
|
|
5987
|
-
amounts: vestingAmounts,
|
|
5988
|
-
tokenURI: t.tokenURI
|
|
5989
|
-
};
|
|
5990
|
-
})();
|
|
5991
|
-
const resolvedTokenFactory = params.modules?.tokenFactory ?? (this.isDoppler404Token(params.token) ? addresses.doppler404Factory : addresses.tokenFactory);
|
|
5992
|
-
if (!resolvedTokenFactory || resolvedTokenFactory === ZERO_ADDRESS2) {
|
|
5993
|
-
throw new Error(
|
|
5994
|
-
"Token factory address not configured. Provide an explicit address via builder.withTokenFactory(...) or ensure chain config includes a valid factory."
|
|
5995
|
-
);
|
|
5996
|
-
}
|
|
6412
|
+
})() : this.buildStandardTokenFactoryData({
|
|
6413
|
+
token: params.token,
|
|
6414
|
+
sale: params.sale,
|
|
6415
|
+
vesting: params.vesting,
|
|
6416
|
+
userAddress: params.userAddress,
|
|
6417
|
+
airlock: params.modules?.airlock ?? addresses.airlock,
|
|
6418
|
+
tokenFactory: resolvedTokenFactory,
|
|
6419
|
+
addresses
|
|
6420
|
+
});
|
|
5997
6421
|
const auctionTokens = params.sale.numTokensToSell * BigInt(params.openingAuction.shareToAuctionBps) / 10000n;
|
|
5998
6422
|
if (auctionTokens <= 0n) {
|
|
5999
6423
|
throw new Error("Opening auction token allocation rounds to zero");
|
|
@@ -6767,69 +7191,23 @@ var DopplerFactory = class {
|
|
|
6767
7191
|
["bytes", "bytes"],
|
|
6768
7192
|
[openingAuction_default, initHashData]
|
|
6769
7193
|
)
|
|
6770
|
-
);
|
|
6771
|
-
const encodedTokenFactoryData = params.tokenVariant === "doppler404" ? (() => {
|
|
6772
|
-
const t = params.tokenFactoryData;
|
|
6773
|
-
return viem.encodeAbiParameters(
|
|
6774
|
-
[
|
|
6775
|
-
{ type: "string" },
|
|
6776
|
-
{ type: "string" },
|
|
6777
|
-
{ type: "string" },
|
|
6778
|
-
{ type: "uint256" }
|
|
6779
|
-
],
|
|
6780
|
-
[t.name, t.symbol, t.baseURI, t.unit ?? 1000n]
|
|
6781
|
-
);
|
|
6782
|
-
})() : (() => {
|
|
6783
|
-
const t = params.tokenFactoryData;
|
|
6784
|
-
return viem.encodeAbiParameters(
|
|
6785
|
-
[
|
|
6786
|
-
{ type: "string" },
|
|
6787
|
-
{ type: "string" },
|
|
6788
|
-
{ type: "uint256" },
|
|
6789
|
-
{ type: "uint256" },
|
|
6790
|
-
{ type: "address[]" },
|
|
6791
|
-
{ type: "uint256[]" },
|
|
6792
|
-
{ type: "string" }
|
|
6793
|
-
],
|
|
6794
|
-
[
|
|
6795
|
-
t.name,
|
|
6796
|
-
t.symbol,
|
|
6797
|
-
t.yearlyMintRate,
|
|
6798
|
-
t.vestingDuration,
|
|
6799
|
-
t.recipients,
|
|
6800
|
-
t.amounts,
|
|
6801
|
-
t.tokenURI
|
|
6802
|
-
]
|
|
6803
|
-
);
|
|
6804
|
-
})();
|
|
6805
|
-
let tokenInitHash;
|
|
6806
|
-
if (params.tokenVariant === "doppler404") {
|
|
6807
|
-
const t = params.tokenFactoryData;
|
|
6808
|
-
const initData = viem.encodeAbiParameters(
|
|
6809
|
-
[
|
|
6810
|
-
{ type: "string" },
|
|
6811
|
-
{ type: "string" },
|
|
6812
|
-
{ type: "uint256" },
|
|
6813
|
-
{ type: "address" },
|
|
6814
|
-
{ type: "address" },
|
|
6815
|
-
{ type: "string" }
|
|
6816
|
-
],
|
|
6817
|
-
[
|
|
6818
|
-
t.name,
|
|
6819
|
-
t.symbol,
|
|
6820
|
-
params.initialSupply,
|
|
6821
|
-
params.airlock,
|
|
6822
|
-
params.airlock,
|
|
6823
|
-
t.baseURI
|
|
6824
|
-
]
|
|
6825
|
-
);
|
|
6826
|
-
tokenInitHash = viem.keccak256(
|
|
6827
|
-
viem.encodePacked(
|
|
6828
|
-
["bytes", "bytes"],
|
|
6829
|
-
[dopplerDN404_default, initData]
|
|
6830
|
-
)
|
|
7194
|
+
);
|
|
7195
|
+
const encodedTokenFactoryData = params.tokenVariant === "doppler404" ? (() => {
|
|
7196
|
+
const t = params.tokenFactoryData;
|
|
7197
|
+
return viem.encodeAbiParameters(
|
|
7198
|
+
[
|
|
7199
|
+
{ type: "string" },
|
|
7200
|
+
{ type: "string" },
|
|
7201
|
+
{ type: "string" },
|
|
7202
|
+
{ type: "uint256" }
|
|
7203
|
+
],
|
|
7204
|
+
[t.name, t.symbol, t.baseURI, t.unit ?? 1000n]
|
|
6831
7205
|
);
|
|
6832
|
-
}
|
|
7206
|
+
})() : this.encodeStandardTokenFactoryData(
|
|
7207
|
+
params.tokenFactoryData
|
|
7208
|
+
);
|
|
7209
|
+
let tokenInitHash;
|
|
7210
|
+
if (params.tokenVariant === "doppler404") {
|
|
6833
7211
|
const t = params.tokenFactoryData;
|
|
6834
7212
|
const initData = viem.encodeAbiParameters(
|
|
6835
7213
|
[
|
|
@@ -6838,10 +7216,6 @@ var DopplerFactory = class {
|
|
|
6838
7216
|
{ type: "uint256" },
|
|
6839
7217
|
{ type: "address" },
|
|
6840
7218
|
{ type: "address" },
|
|
6841
|
-
{ type: "uint256" },
|
|
6842
|
-
{ type: "uint256" },
|
|
6843
|
-
{ type: "address[]" },
|
|
6844
|
-
{ type: "uint256[]" },
|
|
6845
7219
|
{ type: "string" }
|
|
6846
7220
|
],
|
|
6847
7221
|
[
|
|
@@ -6850,23 +7224,20 @@ var DopplerFactory = class {
|
|
|
6850
7224
|
params.initialSupply,
|
|
6851
7225
|
params.airlock,
|
|
6852
7226
|
params.airlock,
|
|
6853
|
-
t.
|
|
6854
|
-
t.vestingDuration,
|
|
6855
|
-
t.recipients,
|
|
6856
|
-
t.amounts,
|
|
6857
|
-
t.tokenURI
|
|
7227
|
+
t.baseURI
|
|
6858
7228
|
]
|
|
6859
7229
|
);
|
|
6860
|
-
const isTokenFactory802 = params.tokenFactory.toLowerCase() === TOKEN_FACTORY_80_ADDRESS2;
|
|
6861
7230
|
tokenInitHash = viem.keccak256(
|
|
6862
7231
|
viem.encodePacked(
|
|
6863
7232
|
["bytes", "bytes"],
|
|
6864
|
-
[
|
|
6865
|
-
isTokenFactory802 ? derc2080_default : derc20_default,
|
|
6866
|
-
initData
|
|
6867
|
-
]
|
|
7233
|
+
[dopplerDN404_default, initData]
|
|
6868
7234
|
)
|
|
6869
7235
|
);
|
|
7236
|
+
} else {
|
|
7237
|
+
tokenInitHash = this.computeStandardTokenInitHash(
|
|
7238
|
+
params.tokenFactoryData,
|
|
7239
|
+
params.tokenFactory
|
|
7240
|
+
);
|
|
6870
7241
|
}
|
|
6871
7242
|
const isToken0 = isToken0Expected(params.numeraire);
|
|
6872
7243
|
const numeraireBigInt = BigInt(params.numeraire);
|
|
@@ -7542,6 +7913,18 @@ var DopplerFactory = class {
|
|
|
7542
7913
|
]
|
|
7543
7914
|
);
|
|
7544
7915
|
}
|
|
7916
|
+
const resolvedTokenFactory = params.modules?.tokenFactory ?? (this.isDoppler404Token(params.token) ? addresses.doppler404Factory : this.usesDerc20V2Vesting(params.vesting) ? addresses.derc20V2Factory : addresses.tokenFactory);
|
|
7917
|
+
if (!resolvedTokenFactory || resolvedTokenFactory === ZERO_ADDRESS2) {
|
|
7918
|
+
throw new Error(
|
|
7919
|
+
"Token factory address not configured. Provide an explicit address or ensure chain config includes a valid factory."
|
|
7920
|
+
);
|
|
7921
|
+
}
|
|
7922
|
+
this.assertStandardTokenFactoryCompatibility({
|
|
7923
|
+
token: params.token,
|
|
7924
|
+
vesting: params.vesting,
|
|
7925
|
+
tokenFactory: resolvedTokenFactory,
|
|
7926
|
+
addresses
|
|
7927
|
+
});
|
|
7545
7928
|
let tokenFactoryData;
|
|
7546
7929
|
if (this.isDoppler404Token(params.token)) {
|
|
7547
7930
|
const token404 = params.token;
|
|
@@ -7556,41 +7939,17 @@ var DopplerFactory = class {
|
|
|
7556
7939
|
[token404.name, token404.symbol, token404.baseURI, unit]
|
|
7557
7940
|
);
|
|
7558
7941
|
} else {
|
|
7559
|
-
const
|
|
7560
|
-
|
|
7561
|
-
|
|
7562
|
-
|
|
7563
|
-
|
|
7564
|
-
|
|
7565
|
-
|
|
7566
|
-
|
|
7567
|
-
|
|
7568
|
-
|
|
7569
|
-
|
|
7570
|
-
vestingAmounts = [
|
|
7571
|
-
params.sale.initialSupply - params.sale.numTokensToSell
|
|
7572
|
-
];
|
|
7573
|
-
}
|
|
7574
|
-
}
|
|
7575
|
-
tokenFactoryData = viem.encodeAbiParameters(
|
|
7576
|
-
[
|
|
7577
|
-
{ type: "string" },
|
|
7578
|
-
{ type: "string" },
|
|
7579
|
-
{ type: "uint256" },
|
|
7580
|
-
{ type: "uint256" },
|
|
7581
|
-
{ type: "address[]" },
|
|
7582
|
-
{ type: "uint256[]" },
|
|
7583
|
-
{ type: "string" }
|
|
7584
|
-
],
|
|
7585
|
-
[
|
|
7586
|
-
tokenStd.name,
|
|
7587
|
-
tokenStd.symbol,
|
|
7588
|
-
yearlyMintRate,
|
|
7589
|
-
BigInt(vestingDuration),
|
|
7590
|
-
vestingRecipients,
|
|
7591
|
-
vestingAmounts,
|
|
7592
|
-
tokenStd.tokenURI
|
|
7593
|
-
]
|
|
7942
|
+
const standardTokenFactoryData = this.buildStandardTokenFactoryData({
|
|
7943
|
+
token: params.token,
|
|
7944
|
+
sale: params.sale,
|
|
7945
|
+
vesting: params.vesting,
|
|
7946
|
+
userAddress: params.userAddress,
|
|
7947
|
+
airlock: params.modules?.airlock ?? addresses.airlock,
|
|
7948
|
+
tokenFactory: resolvedTokenFactory,
|
|
7949
|
+
addresses
|
|
7950
|
+
});
|
|
7951
|
+
tokenFactoryData = this.encodeStandardTokenFactoryData(
|
|
7952
|
+
standardTokenFactoryData
|
|
7594
7953
|
);
|
|
7595
7954
|
}
|
|
7596
7955
|
const governanceFactoryData = (() => {
|
|
@@ -7619,12 +7978,6 @@ var DopplerFactory = class {
|
|
|
7619
7978
|
);
|
|
7620
7979
|
})();
|
|
7621
7980
|
const salt = this.generateRandomSalt(params.userAddress);
|
|
7622
|
-
const resolvedTokenFactory = params.modules?.tokenFactory ?? (this.isDoppler404Token(params.token) ? addresses.doppler404Factory : addresses.tokenFactory);
|
|
7623
|
-
if (!resolvedTokenFactory || resolvedTokenFactory === ZERO_ADDRESS2) {
|
|
7624
|
-
throw new Error(
|
|
7625
|
-
"Token factory address not configured. Provide an explicit address or ensure chain config includes a valid factory."
|
|
7626
|
-
);
|
|
7627
|
-
}
|
|
7628
7981
|
const resolvedInitializer = (() => {
|
|
7629
7982
|
if (useDopplerHookInitializer) {
|
|
7630
7983
|
return params.modules?.dopplerHookInitializer ?? addresses.dopplerHookInitializer;
|
|
@@ -7877,6 +8230,109 @@ var DopplerFactory = class {
|
|
|
7877
8230
|
const rounded = Math.floor(MAX_TICK / tickSpacing) * tickSpacing;
|
|
7878
8231
|
return rounded;
|
|
7879
8232
|
}
|
|
8233
|
+
validateVestingConfig(sale, vesting) {
|
|
8234
|
+
if (!vesting) {
|
|
8235
|
+
return;
|
|
8236
|
+
}
|
|
8237
|
+
const cliffDuration = vesting.cliffDuration ?? 0;
|
|
8238
|
+
const duration = vesting.duration ?? 0;
|
|
8239
|
+
const hasCustomSchedules = this.hasCustomV2Schedules(vesting);
|
|
8240
|
+
if (hasCustomSchedules && (cliffDuration > 0 || duration > 0)) {
|
|
8241
|
+
throw new Error(
|
|
8242
|
+
"Use vesting.schedules instead of top-level duration/cliffDuration when configuring multiple vesting schedules"
|
|
8243
|
+
);
|
|
8244
|
+
}
|
|
8245
|
+
if (vesting.recipients && vesting.amounts) {
|
|
8246
|
+
if (vesting.recipients.length !== vesting.amounts.length) {
|
|
8247
|
+
throw new Error(
|
|
8248
|
+
"Vesting recipients and amounts arrays must have the same length"
|
|
8249
|
+
);
|
|
8250
|
+
}
|
|
8251
|
+
if (vesting.recipients.length === 0) {
|
|
8252
|
+
throw new Error("Vesting recipients array cannot be empty");
|
|
8253
|
+
}
|
|
8254
|
+
const totalVested = vesting.amounts.reduce((sum, amt) => sum + amt, 0n);
|
|
8255
|
+
const availableForVesting = sale.initialSupply - sale.numTokensToSell;
|
|
8256
|
+
if (totalVested > availableForVesting) {
|
|
8257
|
+
throw new Error(
|
|
8258
|
+
`Total vesting amount (${totalVested}) exceeds available tokens (${availableForVesting})`
|
|
8259
|
+
);
|
|
8260
|
+
}
|
|
8261
|
+
} else {
|
|
8262
|
+
const vestedAmount = sale.initialSupply - sale.numTokensToSell;
|
|
8263
|
+
if (vestedAmount <= 0n) {
|
|
8264
|
+
throw new Error("No tokens available for vesting");
|
|
8265
|
+
}
|
|
8266
|
+
}
|
|
8267
|
+
if (hasCustomSchedules) {
|
|
8268
|
+
const schedules = vesting.schedules;
|
|
8269
|
+
if (!schedules || schedules.length === 0) {
|
|
8270
|
+
throw new Error(
|
|
8271
|
+
"Vesting schedules are required when using scheduleIds or multiple vesting schedules"
|
|
8272
|
+
);
|
|
8273
|
+
}
|
|
8274
|
+
const recipientCount = vesting.recipients && vesting.amounts ? vesting.recipients.length : 1;
|
|
8275
|
+
if (vesting.scheduleIds) {
|
|
8276
|
+
if (vesting.scheduleIds.length !== recipientCount) {
|
|
8277
|
+
throw new Error(
|
|
8278
|
+
"Vesting scheduleIds array must have the same length as vesting recipients"
|
|
8279
|
+
);
|
|
8280
|
+
}
|
|
8281
|
+
for (const [index, scheduleId] of vesting.scheduleIds.entries()) {
|
|
8282
|
+
this.validateUint64LikeNumber(
|
|
8283
|
+
scheduleId,
|
|
8284
|
+
`Vesting scheduleIds[${index}]`
|
|
8285
|
+
);
|
|
8286
|
+
if (scheduleId >= schedules.length) {
|
|
8287
|
+
throw new Error(
|
|
8288
|
+
`Vesting scheduleIds[${index}] references missing schedule ${scheduleId}`
|
|
8289
|
+
);
|
|
8290
|
+
}
|
|
8291
|
+
}
|
|
8292
|
+
} else if (schedules.length !== 1 && schedules.length !== recipientCount) {
|
|
8293
|
+
throw new Error(
|
|
8294
|
+
"Vesting schedules must either contain exactly one shared schedule or one schedule per recipient when scheduleIds are omitted"
|
|
8295
|
+
);
|
|
8296
|
+
}
|
|
8297
|
+
for (const [index, schedule] of schedules.entries()) {
|
|
8298
|
+
const scheduleCliff = schedule.cliffDuration ?? 0;
|
|
8299
|
+
const scheduleDuration = schedule.duration ?? 0;
|
|
8300
|
+
this.validateUint64LikeNumber(
|
|
8301
|
+
scheduleCliff,
|
|
8302
|
+
`Vesting schedules[${index}].cliffDuration`
|
|
8303
|
+
);
|
|
8304
|
+
this.validateUint64LikeNumber(
|
|
8305
|
+
scheduleDuration,
|
|
8306
|
+
`Vesting schedules[${index}].duration`
|
|
8307
|
+
);
|
|
8308
|
+
if (scheduleCliff > scheduleDuration) {
|
|
8309
|
+
throw new Error(
|
|
8310
|
+
`Vesting schedules[${index}].cliffDuration cannot exceed duration`
|
|
8311
|
+
);
|
|
8312
|
+
}
|
|
8313
|
+
if (scheduleCliff > 0 && scheduleDuration > 0 && scheduleDuration < DERC20_V2_MIN_VESTING_DURATION) {
|
|
8314
|
+
throw new Error(
|
|
8315
|
+
`Vesting schedules[${index}].duration must be 0 or at least ${DERC20_V2_MIN_VESTING_DURATION} seconds when using cliffs`
|
|
8316
|
+
);
|
|
8317
|
+
}
|
|
8318
|
+
}
|
|
8319
|
+
return;
|
|
8320
|
+
}
|
|
8321
|
+
if (cliffDuration < 0) {
|
|
8322
|
+
throw new Error("Vesting cliff duration cannot be negative");
|
|
8323
|
+
}
|
|
8324
|
+
if (duration < 0) {
|
|
8325
|
+
throw new Error("Vesting duration cannot be negative");
|
|
8326
|
+
}
|
|
8327
|
+
if (cliffDuration > duration) {
|
|
8328
|
+
throw new Error("Vesting cliff duration cannot exceed vesting duration");
|
|
8329
|
+
}
|
|
8330
|
+
if (cliffDuration > 0 && duration > 0 && duration < DERC20_V2_MIN_VESTING_DURATION) {
|
|
8331
|
+
throw new Error(
|
|
8332
|
+
`Vesting duration must be 0 or at least ${DERC20_V2_MIN_VESTING_DURATION} seconds when using cliffs`
|
|
8333
|
+
);
|
|
8334
|
+
}
|
|
8335
|
+
}
|
|
7880
8336
|
validateStaticAuctionParams(params) {
|
|
7881
8337
|
if (!params.token.name || params.token.name.trim().length === 0) {
|
|
7882
8338
|
throw new Error("Token name is required");
|
|
@@ -7914,33 +8370,7 @@ var DopplerFactory = class {
|
|
|
7914
8370
|
if (params.sale.numTokensToSell > params.sale.initialSupply) {
|
|
7915
8371
|
throw new Error("Cannot sell more tokens than initial supply");
|
|
7916
8372
|
}
|
|
7917
|
-
|
|
7918
|
-
if (params.vesting.recipients && params.vesting.amounts) {
|
|
7919
|
-
if (params.vesting.recipients.length !== params.vesting.amounts.length) {
|
|
7920
|
-
throw new Error(
|
|
7921
|
-
"Vesting recipients and amounts arrays must have the same length"
|
|
7922
|
-
);
|
|
7923
|
-
}
|
|
7924
|
-
if (params.vesting.recipients.length === 0) {
|
|
7925
|
-
throw new Error("Vesting recipients array cannot be empty");
|
|
7926
|
-
}
|
|
7927
|
-
const totalVested = params.vesting.amounts.reduce(
|
|
7928
|
-
(sum, amt) => sum + amt,
|
|
7929
|
-
BigInt(0)
|
|
7930
|
-
);
|
|
7931
|
-
const availableForVesting = params.sale.initialSupply - params.sale.numTokensToSell;
|
|
7932
|
-
if (totalVested > availableForVesting) {
|
|
7933
|
-
throw new Error(
|
|
7934
|
-
`Total vesting amount (${totalVested}) exceeds available tokens (${availableForVesting})`
|
|
7935
|
-
);
|
|
7936
|
-
}
|
|
7937
|
-
} else {
|
|
7938
|
-
const vestedAmount = params.sale.initialSupply - params.sale.numTokensToSell;
|
|
7939
|
-
if (vestedAmount <= BigInt(0)) {
|
|
7940
|
-
throw new Error("No tokens available for vesting");
|
|
7941
|
-
}
|
|
7942
|
-
}
|
|
7943
|
-
}
|
|
8373
|
+
this.validateVestingConfig(params.sale, params.vesting);
|
|
7944
8374
|
if (params.migration.type === "dopplerHook") {
|
|
7945
8375
|
throw new Error(
|
|
7946
8376
|
"dopplerHook migration is only supported for dynamic auctions"
|
|
@@ -8005,6 +8435,7 @@ var DopplerFactory = class {
|
|
|
8005
8435
|
if (params.sale.numTokensToSell > params.sale.initialSupply) {
|
|
8006
8436
|
throw new Error("Cannot sell more tokens than initial supply");
|
|
8007
8437
|
}
|
|
8438
|
+
this.validateVestingConfig(params.sale, params.vesting);
|
|
8008
8439
|
if (params.auction.duration <= 0) {
|
|
8009
8440
|
throw new Error("Auction duration must be positive");
|
|
8010
8441
|
}
|
|
@@ -8233,28 +8664,7 @@ var DopplerFactory = class {
|
|
|
8233
8664
|
throw new Error("Cannot sell more tokens than initial supply");
|
|
8234
8665
|
}
|
|
8235
8666
|
this.resolveMulticurveInitializerMode(params);
|
|
8236
|
-
|
|
8237
|
-
if (params.vesting.recipients && params.vesting.amounts) {
|
|
8238
|
-
if (params.vesting.recipients.length !== params.vesting.amounts.length) {
|
|
8239
|
-
throw new Error(
|
|
8240
|
-
"Vesting recipients and amounts arrays must have the same length"
|
|
8241
|
-
);
|
|
8242
|
-
}
|
|
8243
|
-
if (params.vesting.recipients.length === 0) {
|
|
8244
|
-
throw new Error("Vesting recipients array cannot be empty");
|
|
8245
|
-
}
|
|
8246
|
-
const totalVested = params.vesting.amounts.reduce(
|
|
8247
|
-
(sum, amt) => sum + amt,
|
|
8248
|
-
BigInt(0)
|
|
8249
|
-
);
|
|
8250
|
-
const availableForVesting = params.sale.initialSupply - params.sale.numTokensToSell;
|
|
8251
|
-
if (totalVested > availableForVesting) {
|
|
8252
|
-
throw new Error(
|
|
8253
|
-
`Total vesting amount (${totalVested}) exceeds available tokens (${availableForVesting})`
|
|
8254
|
-
);
|
|
8255
|
-
}
|
|
8256
|
-
}
|
|
8257
|
-
}
|
|
8667
|
+
this.validateVestingConfig(params.sale, params.vesting);
|
|
8258
8668
|
if (params.pool.beneficiaries && params.pool.beneficiaries.length > 0) {
|
|
8259
8669
|
const beneficiaries = params.pool.beneficiaries;
|
|
8260
8670
|
const totalShares = beneficiaries.reduce((sum, b) => sum + b.shares, 0n);
|
|
@@ -8654,37 +9064,9 @@ var DopplerFactory = class {
|
|
|
8654
9064
|
],
|
|
8655
9065
|
[t.name, t.symbol, t.baseURI, t.unit ?? 1000n]
|
|
8656
9066
|
);
|
|
8657
|
-
})() : (
|
|
8658
|
-
|
|
8659
|
-
|
|
8660
|
-
symbol,
|
|
8661
|
-
yearlyMintRate,
|
|
8662
|
-
vestingDuration,
|
|
8663
|
-
recipients,
|
|
8664
|
-
amounts,
|
|
8665
|
-
tokenURI
|
|
8666
|
-
} = params.tokenFactoryData;
|
|
8667
|
-
return viem.encodeAbiParameters(
|
|
8668
|
-
[
|
|
8669
|
-
{ type: "string" },
|
|
8670
|
-
{ type: "string" },
|
|
8671
|
-
{ type: "uint256" },
|
|
8672
|
-
{ type: "uint256" },
|
|
8673
|
-
{ type: "address[]" },
|
|
8674
|
-
{ type: "uint256[]" },
|
|
8675
|
-
{ type: "string" }
|
|
8676
|
-
],
|
|
8677
|
-
[
|
|
8678
|
-
name,
|
|
8679
|
-
symbol,
|
|
8680
|
-
yearlyMintRate,
|
|
8681
|
-
vestingDuration,
|
|
8682
|
-
recipients,
|
|
8683
|
-
amounts,
|
|
8684
|
-
tokenURI
|
|
8685
|
-
]
|
|
8686
|
-
);
|
|
8687
|
-
})();
|
|
9067
|
+
})() : this.encodeStandardTokenFactoryData(
|
|
9068
|
+
params.tokenFactoryData
|
|
9069
|
+
);
|
|
8688
9070
|
let tokenInitHash;
|
|
8689
9071
|
if (params.tokenVariant === "doppler404") {
|
|
8690
9072
|
const { name, symbol, baseURI } = params.tokenFactoryData;
|
|
@@ -8707,47 +9089,45 @@ var DopplerFactory = class {
|
|
|
8707
9089
|
)
|
|
8708
9090
|
);
|
|
8709
9091
|
} else {
|
|
8710
|
-
const
|
|
8711
|
-
|
|
8712
|
-
|
|
8713
|
-
|
|
8714
|
-
|
|
8715
|
-
|
|
8716
|
-
|
|
8717
|
-
|
|
8718
|
-
|
|
8719
|
-
|
|
8720
|
-
|
|
8721
|
-
|
|
8722
|
-
|
|
8723
|
-
|
|
8724
|
-
|
|
8725
|
-
|
|
8726
|
-
|
|
8727
|
-
|
|
8728
|
-
|
|
8729
|
-
|
|
8730
|
-
|
|
8731
|
-
|
|
8732
|
-
|
|
8733
|
-
|
|
8734
|
-
|
|
8735
|
-
|
|
8736
|
-
|
|
8737
|
-
|
|
8738
|
-
|
|
8739
|
-
|
|
8740
|
-
|
|
8741
|
-
|
|
8742
|
-
|
|
8743
|
-
|
|
8744
|
-
|
|
8745
|
-
|
|
8746
|
-
|
|
8747
|
-
|
|
8748
|
-
|
|
8749
|
-
viem.encodePacked(["bytes", "bytes"], [bytecode, initHashData])
|
|
8750
|
-
);
|
|
9092
|
+
const standardTokenFactoryData = params.tokenFactoryData;
|
|
9093
|
+
if (standardTokenFactoryData.kind === "v2") {
|
|
9094
|
+
tokenInitHash = this.computeStandardTokenInitHash(
|
|
9095
|
+
standardTokenFactoryData,
|
|
9096
|
+
params.tokenFactory
|
|
9097
|
+
);
|
|
9098
|
+
} else {
|
|
9099
|
+
const initHashData = viem.encodeAbiParameters(
|
|
9100
|
+
[
|
|
9101
|
+
{ type: "string" },
|
|
9102
|
+
{ type: "string" },
|
|
9103
|
+
{ type: "uint256" },
|
|
9104
|
+
{ type: "address" },
|
|
9105
|
+
{ type: "address" },
|
|
9106
|
+
{ type: "uint256" },
|
|
9107
|
+
{ type: "uint256" },
|
|
9108
|
+
{ type: "address[]" },
|
|
9109
|
+
{ type: "uint256[]" },
|
|
9110
|
+
{ type: "string" }
|
|
9111
|
+
],
|
|
9112
|
+
[
|
|
9113
|
+
standardTokenFactoryData.name,
|
|
9114
|
+
standardTokenFactoryData.symbol,
|
|
9115
|
+
standardTokenFactoryData.initialSupply,
|
|
9116
|
+
standardTokenFactoryData.airlock,
|
|
9117
|
+
standardTokenFactoryData.airlock,
|
|
9118
|
+
standardTokenFactoryData.yearlyMintRate,
|
|
9119
|
+
standardTokenFactoryData.vestingDuration,
|
|
9120
|
+
standardTokenFactoryData.recipients,
|
|
9121
|
+
standardTokenFactoryData.amounts,
|
|
9122
|
+
standardTokenFactoryData.tokenURI
|
|
9123
|
+
]
|
|
9124
|
+
);
|
|
9125
|
+
const isTokenFactory802 = params.tokenFactory.toLowerCase() === TOKEN_FACTORY_80_ADDRESS2;
|
|
9126
|
+
const bytecode = isTokenFactory802 ? derc2080_default : params.customDerc20Bytecode ?? derc20_default;
|
|
9127
|
+
tokenInitHash = viem.keccak256(
|
|
9128
|
+
viem.encodePacked(["bytes", "bytes"], [bytecode, initHashData])
|
|
9129
|
+
);
|
|
9130
|
+
}
|
|
8751
9131
|
}
|
|
8752
9132
|
const flags = BigInt(
|
|
8753
9133
|
1 << 13 | // BEFORE_INITIALIZE_FLAG
|
|
@@ -13028,6 +13408,108 @@ var Derc20 = class _Derc20 {
|
|
|
13028
13408
|
);
|
|
13029
13409
|
}
|
|
13030
13410
|
};
|
|
13411
|
+
|
|
13412
|
+
// src/evm/entities/token/derc20/Derc20V2.ts
|
|
13413
|
+
var Derc20V2 = class extends Derc20 {
|
|
13414
|
+
async getVestingScheduleCount() {
|
|
13415
|
+
return await this.rpc.readContract({
|
|
13416
|
+
address: this.address,
|
|
13417
|
+
abi: derc20V2Abi,
|
|
13418
|
+
functionName: "vestingScheduleCount"
|
|
13419
|
+
});
|
|
13420
|
+
}
|
|
13421
|
+
async getVestingSchedule(scheduleId) {
|
|
13422
|
+
const result = await this.rpc.readContract({
|
|
13423
|
+
address: this.address,
|
|
13424
|
+
abi: derc20V2Abi,
|
|
13425
|
+
functionName: "vestingSchedules",
|
|
13426
|
+
args: [scheduleId]
|
|
13427
|
+
});
|
|
13428
|
+
return {
|
|
13429
|
+
cliffDuration: BigInt(result[0]),
|
|
13430
|
+
duration: BigInt(result[1])
|
|
13431
|
+
};
|
|
13432
|
+
}
|
|
13433
|
+
async getScheduleIdsOf(beneficiary) {
|
|
13434
|
+
const result = await this.rpc.readContract({
|
|
13435
|
+
address: this.address,
|
|
13436
|
+
abi: derc20V2Abi,
|
|
13437
|
+
functionName: "getScheduleIdsOf",
|
|
13438
|
+
args: [beneficiary]
|
|
13439
|
+
});
|
|
13440
|
+
return Array.from(result);
|
|
13441
|
+
}
|
|
13442
|
+
async getTotalAllocatedOf(beneficiary) {
|
|
13443
|
+
return await this.rpc.readContract({
|
|
13444
|
+
address: this.address,
|
|
13445
|
+
abi: derc20V2Abi,
|
|
13446
|
+
functionName: "totalAllocatedOf",
|
|
13447
|
+
args: [beneficiary]
|
|
13448
|
+
});
|
|
13449
|
+
}
|
|
13450
|
+
async getAvailableVestedAmountForSchedule(beneficiary, scheduleId) {
|
|
13451
|
+
return await this.rpc.readContract({
|
|
13452
|
+
address: this.address,
|
|
13453
|
+
abi: derc20V2Abi,
|
|
13454
|
+
functionName: "computeAvailableVestedAmount",
|
|
13455
|
+
args: [beneficiary, scheduleId]
|
|
13456
|
+
});
|
|
13457
|
+
}
|
|
13458
|
+
async getVestingDataForSchedule(beneficiary, scheduleId) {
|
|
13459
|
+
const result = await this.rpc.readContract({
|
|
13460
|
+
address: this.address,
|
|
13461
|
+
abi: derc20V2Abi,
|
|
13462
|
+
functionName: "vestingOf",
|
|
13463
|
+
args: [beneficiary, scheduleId]
|
|
13464
|
+
});
|
|
13465
|
+
return {
|
|
13466
|
+
totalAmount: result[0],
|
|
13467
|
+
releasedAmount: result[1]
|
|
13468
|
+
};
|
|
13469
|
+
}
|
|
13470
|
+
async releaseSchedule(scheduleId, options) {
|
|
13471
|
+
if (!this.walletClient) {
|
|
13472
|
+
throw new Error("Wallet client required for write operations");
|
|
13473
|
+
}
|
|
13474
|
+
const { request } = await this.rpc.simulateContract({
|
|
13475
|
+
address: this.address,
|
|
13476
|
+
abi: derc20V2Abi,
|
|
13477
|
+
functionName: "release",
|
|
13478
|
+
args: [scheduleId],
|
|
13479
|
+
account: this.walletClient.account
|
|
13480
|
+
});
|
|
13481
|
+
return await this.walletClient.writeContract(
|
|
13482
|
+
options?.gas ? { ...request, gas: options.gas } : request
|
|
13483
|
+
);
|
|
13484
|
+
}
|
|
13485
|
+
async releaseFor(beneficiary, scheduleId, options) {
|
|
13486
|
+
if (!this.walletClient) {
|
|
13487
|
+
throw new Error("Wallet client required for write operations");
|
|
13488
|
+
}
|
|
13489
|
+
if (scheduleId === void 0) {
|
|
13490
|
+
const { request: request2 } = await this.rpc.simulateContract({
|
|
13491
|
+
address: this.address,
|
|
13492
|
+
abi: derc20V2Abi,
|
|
13493
|
+
functionName: "releaseFor",
|
|
13494
|
+
args: [beneficiary],
|
|
13495
|
+
account: this.walletClient.account
|
|
13496
|
+
});
|
|
13497
|
+
return await this.walletClient.writeContract(
|
|
13498
|
+
options?.gas ? { ...request2, gas: options.gas } : request2
|
|
13499
|
+
);
|
|
13500
|
+
}
|
|
13501
|
+
const { request } = await this.rpc.simulateContract({
|
|
13502
|
+
address: this.address,
|
|
13503
|
+
abi: derc20V2Abi,
|
|
13504
|
+
functionName: "releaseFor",
|
|
13505
|
+
args: [beneficiary, scheduleId],
|
|
13506
|
+
account: this.walletClient.account
|
|
13507
|
+
});
|
|
13508
|
+
return await this.walletClient.writeContract(
|
|
13509
|
+
options?.gas ? { ...request, gas: options.gas } : request
|
|
13510
|
+
);
|
|
13511
|
+
}
|
|
13512
|
+
};
|
|
13031
13513
|
var Eth = class {
|
|
13032
13514
|
publicClient;
|
|
13033
13515
|
get rpc() {
|
|
@@ -13083,6 +13565,35 @@ var Eth = class {
|
|
|
13083
13565
|
};
|
|
13084
13566
|
|
|
13085
13567
|
// src/evm/builders/shared.ts
|
|
13568
|
+
var MAX_SAFE_INTEGER_BIGINT = BigInt(Number.MAX_SAFE_INTEGER);
|
|
13569
|
+
function normalizeBuilderVestingScheduleDuration(value, fieldPath) {
|
|
13570
|
+
const duration = value ?? 0n;
|
|
13571
|
+
if (duration < 0n) {
|
|
13572
|
+
throw new RangeError(`${fieldPath} cannot be negative`);
|
|
13573
|
+
}
|
|
13574
|
+
if (duration > MAX_SAFE_INTEGER_BIGINT) {
|
|
13575
|
+
throw new RangeError(`${fieldPath} must be a safe integer`);
|
|
13576
|
+
}
|
|
13577
|
+
return Number(duration);
|
|
13578
|
+
}
|
|
13579
|
+
function normalizeBuilderScheduleId(scheduleId, fieldPath) {
|
|
13580
|
+
if (typeof scheduleId === "bigint") {
|
|
13581
|
+
if (scheduleId < 0n) {
|
|
13582
|
+
throw new RangeError(`${fieldPath} cannot be negative`);
|
|
13583
|
+
}
|
|
13584
|
+
if (scheduleId > MAX_SAFE_INTEGER_BIGINT) {
|
|
13585
|
+
throw new RangeError(`${fieldPath} must be a safe integer`);
|
|
13586
|
+
}
|
|
13587
|
+
return Number(scheduleId);
|
|
13588
|
+
}
|
|
13589
|
+
if (!Number.isSafeInteger(scheduleId)) {
|
|
13590
|
+
throw new RangeError(`${fieldPath} must be a safe integer`);
|
|
13591
|
+
}
|
|
13592
|
+
if (scheduleId < 0) {
|
|
13593
|
+
throw new RangeError(`${fieldPath} cannot be negative`);
|
|
13594
|
+
}
|
|
13595
|
+
return scheduleId;
|
|
13596
|
+
}
|
|
13086
13597
|
function computeTicks(priceRange, tickSpacing) {
|
|
13087
13598
|
const startTick = Math.floor(
|
|
13088
13599
|
Math.log(priceRange.startPrice) / Math.log(1.0001) / tickSpacing
|
|
@@ -13378,11 +13889,24 @@ var StaticAuctionBuilder = class _StaticAuctionBuilder {
|
|
|
13378
13889
|
this.vesting = void 0;
|
|
13379
13890
|
return this;
|
|
13380
13891
|
}
|
|
13892
|
+
const hasCustomSchedules = (params.schedules?.length ?? 0) > 0 || (params.scheduleIds?.length ?? 0) > 0;
|
|
13381
13893
|
this.vesting = {
|
|
13382
|
-
duration: Number(
|
|
13894
|
+
duration: Number(
|
|
13895
|
+
params.duration ?? (hasCustomSchedules ? 0n : DEFAULT_V3_VESTING_DURATION)
|
|
13896
|
+
),
|
|
13383
13897
|
cliffDuration: params.cliffDuration ?? 0,
|
|
13384
13898
|
recipients: params.recipients,
|
|
13385
|
-
amounts: params.amounts
|
|
13899
|
+
amounts: params.amounts,
|
|
13900
|
+
schedules: params.schedules?.map((schedule) => ({
|
|
13901
|
+
duration: normalizeBuilderVestingScheduleDuration(
|
|
13902
|
+
schedule.duration,
|
|
13903
|
+
"Vesting schedule duration"
|
|
13904
|
+
),
|
|
13905
|
+
cliffDuration: schedule.cliffDuration ?? 0
|
|
13906
|
+
})),
|
|
13907
|
+
scheduleIds: params.scheduleIds?.map(
|
|
13908
|
+
(scheduleId, index) => normalizeBuilderScheduleId(scheduleId, `Vesting scheduleIds[${index}]`)
|
|
13909
|
+
)
|
|
13386
13910
|
};
|
|
13387
13911
|
return this;
|
|
13388
13912
|
}
|
|
@@ -13714,7 +14238,17 @@ var DynamicAuctionBuilder = class _DynamicAuctionBuilder {
|
|
|
13714
14238
|
duration: Number(params.duration ?? 0n),
|
|
13715
14239
|
cliffDuration: params.cliffDuration ?? 0,
|
|
13716
14240
|
recipients: params.recipients,
|
|
13717
|
-
amounts: params.amounts
|
|
14241
|
+
amounts: params.amounts,
|
|
14242
|
+
schedules: params.schedules?.map((schedule) => ({
|
|
14243
|
+
duration: normalizeBuilderVestingScheduleDuration(
|
|
14244
|
+
schedule.duration,
|
|
14245
|
+
"Vesting schedule duration"
|
|
14246
|
+
),
|
|
14247
|
+
cliffDuration: schedule.cliffDuration ?? 0
|
|
14248
|
+
})),
|
|
14249
|
+
scheduleIds: params.scheduleIds?.map(
|
|
14250
|
+
(scheduleId, index) => normalizeBuilderScheduleId(scheduleId, `Vesting scheduleIds[${index}]`)
|
|
14251
|
+
)
|
|
13718
14252
|
};
|
|
13719
14253
|
return this;
|
|
13720
14254
|
}
|
|
@@ -14320,7 +14854,17 @@ var MulticurveBuilder = class _MulticurveBuilder {
|
|
|
14320
14854
|
duration: Number(params.duration ?? 0n),
|
|
14321
14855
|
cliffDuration: params.cliffDuration ?? 0,
|
|
14322
14856
|
recipients: params.recipients,
|
|
14323
|
-
amounts: params.amounts
|
|
14857
|
+
amounts: params.amounts,
|
|
14858
|
+
schedules: params.schedules?.map((schedule) => ({
|
|
14859
|
+
duration: normalizeBuilderVestingScheduleDuration(
|
|
14860
|
+
schedule.duration,
|
|
14861
|
+
"Vesting schedule duration"
|
|
14862
|
+
),
|
|
14863
|
+
cliffDuration: schedule.cliffDuration ?? 0
|
|
14864
|
+
})),
|
|
14865
|
+
scheduleIds: params.scheduleIds?.map(
|
|
14866
|
+
(scheduleId, index) => normalizeBuilderScheduleId(scheduleId, `Vesting scheduleIds[${index}]`)
|
|
14867
|
+
)
|
|
14324
14868
|
};
|
|
14325
14869
|
return this;
|
|
14326
14870
|
}
|
|
@@ -14709,7 +15253,17 @@ var OpeningAuctionBuilder = class _OpeningAuctionBuilder {
|
|
|
14709
15253
|
duration: Number(params.duration ?? 0n),
|
|
14710
15254
|
cliffDuration: params.cliffDuration ?? 0,
|
|
14711
15255
|
recipients: params.recipients,
|
|
14712
|
-
amounts: params.amounts
|
|
15256
|
+
amounts: params.amounts,
|
|
15257
|
+
schedules: params.schedules?.map((schedule) => ({
|
|
15258
|
+
duration: normalizeBuilderVestingScheduleDuration(
|
|
15259
|
+
schedule.duration,
|
|
15260
|
+
"Vesting schedule duration"
|
|
15261
|
+
),
|
|
15262
|
+
cliffDuration: schedule.cliffDuration ?? 0
|
|
15263
|
+
})),
|
|
15264
|
+
scheduleIds: params.scheduleIds?.map(
|
|
15265
|
+
(scheduleId, index) => normalizeBuilderScheduleId(scheduleId, `Vesting scheduleIds[${index}]`)
|
|
15266
|
+
)
|
|
14713
15267
|
};
|
|
14714
15268
|
return this;
|
|
14715
15269
|
}
|
|
@@ -15155,6 +15709,13 @@ var DopplerSDK = class {
|
|
|
15155
15709
|
getDerc20(tokenAddress) {
|
|
15156
15710
|
return new Derc20(this.publicClient, this.walletClient, tokenAddress);
|
|
15157
15711
|
}
|
|
15712
|
+
/**
|
|
15713
|
+
* Get a DERC20 V2 token instance for interacting with cliffed / multi-schedule vesting tokens
|
|
15714
|
+
* @param tokenAddress The address of the DERC20 V2 token
|
|
15715
|
+
*/
|
|
15716
|
+
getDerc20V2(tokenAddress) {
|
|
15717
|
+
return new Derc20V2(this.publicClient, this.walletClient, tokenAddress);
|
|
15718
|
+
}
|
|
15158
15719
|
/**
|
|
15159
15720
|
* Get information about a static auction pool
|
|
15160
15721
|
* @param poolAddress The address of the pool
|
|
@@ -15277,6 +15838,7 @@ exports.DOPPLER_FLAGS = DOPPLER_FLAGS;
|
|
|
15277
15838
|
exports.DOPPLER_MAX_TICK_SPACING = DOPPLER_MAX_TICK_SPACING;
|
|
15278
15839
|
exports.DYNAMIC_FEE_FLAG = DYNAMIC_FEE_FLAG;
|
|
15279
15840
|
exports.Derc20 = Derc20;
|
|
15841
|
+
exports.Derc20V2 = Derc20V2;
|
|
15280
15842
|
exports.DopplerBytecode = doppler_default;
|
|
15281
15843
|
exports.DopplerDN404Bytecode = dopplerDN404_default;
|
|
15282
15844
|
exports.DopplerFactory = DopplerFactory;
|
|
@@ -15347,6 +15909,7 @@ exports.createAirlockBeneficiary = createAirlockBeneficiary;
|
|
|
15347
15909
|
exports.decayMulticurveInitializerHookAbi = decayMulticurveInitializerHookAbi;
|
|
15348
15910
|
exports.decodeBalanceDelta = decodeBalanceDelta;
|
|
15349
15911
|
exports.derc20Abi = derc20Abi;
|
|
15912
|
+
exports.derc20V2Abi = derc20V2Abi;
|
|
15350
15913
|
exports.dopplerHookAbi = dopplerHookAbi;
|
|
15351
15914
|
exports.dopplerHookInitializerAbi = dopplerHookInitializerAbi;
|
|
15352
15915
|
exports.dopplerLensAbi = dopplerLensAbi;
|