@interest-protocol/blast-core 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/aborts.d.ts +13 -0
- package/dist/aborts.d.ts.map +1 -0
- package/dist/aborts.js +32 -0
- package/dist/aborts.js.map +1 -0
- package/dist/bcs.d.ts +226 -7
- package/dist/bcs.d.ts.map +1 -1
- package/dist/bcs.js +227 -1
- package/dist/bcs.js.map +1 -1
- package/dist/bps.d.ts +25 -0
- package/dist/bps.d.ts.map +1 -0
- package/dist/bps.js +64 -0
- package/dist/bps.js.map +1 -0
- package/dist/bytecode-template.d.ts +14 -3
- package/dist/bytecode-template.d.ts.map +1 -1
- package/dist/bytecode-template.js +61 -6
- package/dist/bytecode-template.js.map +1 -1
- package/dist/deployment.d.ts +59 -0
- package/dist/deployment.d.ts.map +1 -0
- package/dist/deployment.js +172 -0
- package/dist/deployment.js.map +1 -0
- package/dist/effects.d.ts +69 -0
- package/dist/effects.d.ts.map +1 -0
- package/dist/effects.js +143 -0
- package/dist/effects.js.map +1 -0
- package/dist/fee-split.d.ts +55 -0
- package/dist/fee-split.d.ts.map +1 -0
- package/dist/fee-split.js +69 -0
- package/dist/fee-split.js.map +1 -0
- package/dist/index.d.ts +10 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -1
- package/dist/index.js.map +1 -1
- package/dist/integers.d.ts +2 -0
- package/dist/integers.d.ts.map +1 -1
- package/dist/integers.js +8 -0
- package/dist/integers.js.map +1 -1
- package/dist/merkle.d.ts +6 -1
- package/dist/merkle.d.ts.map +1 -1
- package/dist/merkle.js +8 -1
- package/dist/merkle.js.map +1 -1
- package/dist/migration-math.d.ts +13 -2
- package/dist/migration-math.d.ts.map +1 -1
- package/dist/migration-math.js +34 -6
- package/dist/migration-math.js.map +1 -1
- package/dist/migration.d.ts +25 -0
- package/dist/migration.d.ts.map +1 -0
- package/dist/migration.js +43 -0
- package/dist/migration.js.map +1 -0
- package/dist/payout.d.ts +21 -0
- package/dist/payout.d.ts.map +1 -0
- package/dist/payout.js +36 -0
- package/dist/payout.js.map +1 -0
- package/dist/protocol-fees.d.ts +63 -0
- package/dist/protocol-fees.d.ts.map +1 -0
- package/dist/protocol-fees.js +117 -0
- package/dist/protocol-fees.js.map +1 -0
- package/dist/rewards/allocations.d.ts +16 -17
- package/dist/rewards/allocations.d.ts.map +1 -1
- package/dist/rewards/allocations.js +47 -43
- package/dist/rewards/allocations.js.map +1 -1
- package/dist/roles.d.ts +17 -0
- package/dist/roles.d.ts.map +1 -0
- package/dist/roles.js +32 -0
- package/dist/roles.js.map +1 -0
- package/dist/treasury.d.ts +58 -0
- package/dist/treasury.d.ts.map +1 -0
- package/dist/treasury.js +61 -0
- package/dist/treasury.js.map +1 -0
- package/package.json +39 -11
- package/src/aborts.ts +38 -0
- package/src/bcs.ts +374 -1
- package/src/bps.ts +92 -0
- package/src/bytecode-template.ts +78 -6
- package/src/deployment.ts +230 -0
- package/src/effects.ts +247 -0
- package/src/fee-split.ts +103 -0
- package/src/index.ts +10 -1
- package/src/integers.ts +15 -0
- package/src/merkle.ts +11 -1
- package/src/migration-math.ts +38 -6
- package/src/migration.ts +69 -0
- package/src/payout.ts +57 -0
- package/src/protocol-fees.ts +174 -0
- package/src/rewards/allocations.ts +52 -67
- package/src/roles.ts +39 -0
- package/src/treasury.ts +94 -0
- package/dist/rewards/keeper.d.ts +0 -17
- package/dist/rewards/keeper.d.ts.map +0 -1
- package/dist/rewards/keeper.js +0 -21
- package/dist/rewards/keeper.js.map +0 -1
- package/dist/rewards/state.d.ts +0 -55
- package/dist/rewards/state.d.ts.map +0 -1
- package/dist/rewards/state.js +0 -80
- package/dist/rewards/state.js.map +0 -1
- package/dist/timelock.d.ts +0 -15
- package/dist/timelock.d.ts.map +0 -1
- package/dist/timelock.js +0 -30
- package/dist/timelock.js.map +0 -1
- package/src/rewards/keeper.ts +0 -45
- package/src/rewards/state.ts +0 -113
- package/src/timelock.ts +0 -47
package/src/roles.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { CoreDeployment } from "./deployment.ts";
|
|
2
|
+
import { coreType } from "./deployment.ts";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* `blast_core::blast_domain`'s product administration roles, one set for the
|
|
6
|
+
* launchpad, the presale, the vault and the venues. Package roles (upgrade,
|
|
7
|
+
* pause, unpause, cancel) are `blast_admin::package_admin`'s, generic over
|
|
8
|
+
* each package's OTW.
|
|
9
|
+
*/
|
|
10
|
+
export const CORE_ROLES = [
|
|
11
|
+
"TreasuryAdmin",
|
|
12
|
+
"FeeAdmin",
|
|
13
|
+
"ListingAdmin",
|
|
14
|
+
"VenueAdmin",
|
|
15
|
+
"RewardsAdmin",
|
|
16
|
+
"BuybackAdmin",
|
|
17
|
+
"AutoLpAdmin",
|
|
18
|
+
"CreatorAdmin",
|
|
19
|
+
"ClaimSignerAdmin",
|
|
20
|
+
"CancelAdmin",
|
|
21
|
+
] as const;
|
|
22
|
+
|
|
23
|
+
export type CoreRole = (typeof CORE_ROLES)[number];
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* `<core original>::blast_domain::<role>`: the `Role` an `AdminCap` signs in to.
|
|
27
|
+
* Move keys ACL roles by `type_name::with_defining_ids`; the defining ID equals
|
|
28
|
+
* the original ID for the canonical version-1 role types. New role types
|
|
29
|
+
* introduced by upgrades require their actual defining package ID.
|
|
30
|
+
*/
|
|
31
|
+
export function coreRoleType(
|
|
32
|
+
core: Pick<CoreDeployment, "originalPackageId">,
|
|
33
|
+
role: CoreRole,
|
|
34
|
+
): string {
|
|
35
|
+
if (!CORE_ROLES.includes(role)) {
|
|
36
|
+
throw new TypeError(`unknown blast_domain role ${String(role)}`);
|
|
37
|
+
}
|
|
38
|
+
return coreType(core, "blast_domain", role);
|
|
39
|
+
}
|
package/src/treasury.ts
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { bcs } from "@mysten/sui/bcs";
|
|
2
|
+
import type { ClientWithCoreApi } from "@mysten/sui/client";
|
|
3
|
+
import { normalizeStructTag, normalizeSuiObjectId } from "@mysten/sui/utils";
|
|
4
|
+
import type { Proposal } from "./bcs.ts";
|
|
5
|
+
import { addressBcs, delayedBcs, suiUidBcs, unitKeyBcs } from "./bcs.ts";
|
|
6
|
+
import type { CoreDeployment } from "./deployment.ts";
|
|
7
|
+
import { coreType } from "./deployment.ts";
|
|
8
|
+
import { normalizePositiveU64 } from "./integers.ts";
|
|
9
|
+
import type { SharedObjectIdentity } from "./sui.ts";
|
|
10
|
+
|
|
11
|
+
/** BCS layout of `blast_core::blast_treasury::Treasury`. */
|
|
12
|
+
export const treasuryBcs = bcs.struct("Treasury", {
|
|
13
|
+
id: suiUidBcs,
|
|
14
|
+
destination: delayedBcs(unitKeyBcs, addressBcs),
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The one address every Blast fee is paid to: the applied `destination`, the
|
|
19
|
+
* delay the next change waits, and the scheduled change, if any.
|
|
20
|
+
*/
|
|
21
|
+
export type TreasuryState = SharedObjectIdentity & {
|
|
22
|
+
destination: string;
|
|
23
|
+
delayMs: bigint;
|
|
24
|
+
pending: Proposal<string> | null;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The treasury's one delayed key, `blast_treasury::DestinationKey`
|
|
29
|
+
* (`Delayed<DestinationKey, address>`), in the shape of
|
|
30
|
+
* `@interest-protocol/blast-admin-sdk/events`' `DelayedKeySpecs`; decode its
|
|
31
|
+
* events with `decodeDelayedEvent` and the core original package ID.
|
|
32
|
+
*/
|
|
33
|
+
export const treasuryDelayedKeys = {
|
|
34
|
+
Destination: {
|
|
35
|
+
key: "blast_treasury::DestinationKey",
|
|
36
|
+
family: "setting",
|
|
37
|
+
keyBcs: unitKeyBcs,
|
|
38
|
+
valueBcs: addressBcs,
|
|
39
|
+
valueType: "address",
|
|
40
|
+
},
|
|
41
|
+
} as const;
|
|
42
|
+
|
|
43
|
+
export function decodeTreasuryObject(
|
|
44
|
+
object: SharedObjectIdentity & { type: string; content: Uint8Array },
|
|
45
|
+
core: Pick<CoreDeployment, "originalPackageId">,
|
|
46
|
+
): TreasuryState {
|
|
47
|
+
if (
|
|
48
|
+
normalizeStructTag(object.type) !==
|
|
49
|
+
coreType(core, "blast_treasury", "Treasury")
|
|
50
|
+
) {
|
|
51
|
+
throw new TypeError(`object ${object.objectId} is not the Blast treasury`);
|
|
52
|
+
}
|
|
53
|
+
const parsed = treasuryBcs.parse(object.content);
|
|
54
|
+
const objectId = normalizeSuiObjectId(object.objectId);
|
|
55
|
+
if (
|
|
56
|
+
normalizeSuiObjectId(parsed.id.id.bytes) !== objectId ||
|
|
57
|
+
parsed.destination.parent !== objectId
|
|
58
|
+
) {
|
|
59
|
+
throw new TypeError(`treasury ${object.objectId} has a mismatched UID`);
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
objectId,
|
|
63
|
+
initialSharedVersion: normalizePositiveU64(
|
|
64
|
+
"initialSharedVersion",
|
|
65
|
+
object.initialSharedVersion,
|
|
66
|
+
),
|
|
67
|
+
destination: parsed.destination.value,
|
|
68
|
+
delayMs: parsed.destination.delay_ms,
|
|
69
|
+
pending: parsed.destination.pending,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Reads the shared treasury the core deployment records. */
|
|
74
|
+
export async function getTreasury(
|
|
75
|
+
client: ClientWithCoreApi,
|
|
76
|
+
core: Pick<CoreDeployment, "originalPackageId" | "treasury">,
|
|
77
|
+
): Promise<TreasuryState> {
|
|
78
|
+
const { object } = await client.core.getObject({
|
|
79
|
+
objectId: core.treasury.objectId,
|
|
80
|
+
include: { content: true },
|
|
81
|
+
});
|
|
82
|
+
if (object.owner.$kind !== "Shared") {
|
|
83
|
+
throw new TypeError(`treasury ${object.objectId} is not a shared object`);
|
|
84
|
+
}
|
|
85
|
+
return decodeTreasuryObject(
|
|
86
|
+
{
|
|
87
|
+
objectId: object.objectId,
|
|
88
|
+
initialSharedVersion: object.owner.Shared.initialSharedVersion,
|
|
89
|
+
type: object.type,
|
|
90
|
+
content: object.content,
|
|
91
|
+
},
|
|
92
|
+
core,
|
|
93
|
+
);
|
|
94
|
+
}
|
package/dist/rewards/keeper.d.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { RewardLeafDomain, RewardManifest } from "./allocations.ts";
|
|
2
|
-
import type { RewardRoundState } from "./state.ts";
|
|
3
|
-
/**
|
|
4
|
-
* What a `blast_holder_rewards::Round` object commits to. Its checkpoint window
|
|
5
|
-
* and manifest digest are only in the `RoundPublished` event.
|
|
6
|
-
*/
|
|
7
|
-
type RoundCommitment = Pick<RewardRoundState, "vaultId" | "number" | "root" | "leafCount">;
|
|
8
|
-
/**
|
|
9
|
-
* A relayer must compare the public artifact with authoritative chain state
|
|
10
|
-
* before paying. The root commits every leaf; the round object keeps no
|
|
11
|
-
* checkpoints or manifest digest (its `RoundPublished` event does).
|
|
12
|
-
*/
|
|
13
|
-
export declare function assertRewardRoundMatchesManifest(round: RoundCommitment, manifest: RewardManifest, leafDomain: RewardLeafDomain): void;
|
|
14
|
-
/** On-chain claimed bits own retry state; local transaction success logs do not. */
|
|
15
|
-
export declare function pendingRewardAllocations(round: RoundCommitment & Pick<RewardRoundState, "claimed">, manifest: RewardManifest, leafDomain: RewardLeafDomain): import("./allocations.ts").RewardProof[];
|
|
16
|
-
export {};
|
|
17
|
-
//# sourceMappingURL=keeper.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"keeper.d.ts","sourceRoot":"","sources":["../../src/rewards/keeper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEzE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGnD;;;GAGG;AACH,KAAK,eAAe,GAAG,IAAI,CACzB,gBAAgB,EAChB,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,CAC5C,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,gCAAgC,CAC9C,KAAK,EAAE,eAAe,EACtB,QAAQ,EAAE,cAAc,EACxB,UAAU,EAAE,gBAAgB,GAC3B,IAAI,CASN;AAED,oFAAoF;AACpF,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,eAAe,GAAG,IAAI,CAAC,gBAAgB,EAAE,SAAS,CAAC,EAC1D,QAAQ,EAAE,cAAc,EACxB,UAAU,EAAE,gBAAgB,4CAM7B"}
|
package/dist/rewards/keeper.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { validateRewardManifest } from "./allocations.js";
|
|
2
|
-
import { rewardIsClaimed } from "./state.js";
|
|
3
|
-
/**
|
|
4
|
-
* A relayer must compare the public artifact with authoritative chain state
|
|
5
|
-
* before paying. The root commits every leaf; the round object keeps no
|
|
6
|
-
* checkpoints or manifest digest (its `RoundPublished` event does).
|
|
7
|
-
*/
|
|
8
|
-
export function assertRewardRoundMatchesManifest(round, manifest, leafDomain) {
|
|
9
|
-
validateRewardManifest(manifest, leafDomain);
|
|
10
|
-
if (round.vaultId !== manifest.vaultId ||
|
|
11
|
-
round.number !== BigInt(manifest.number) ||
|
|
12
|
-
round.root !== manifest.root ||
|
|
13
|
-
round.leafCount !== manifest.allocations.length)
|
|
14
|
-
throw new Error("manifest does not match funded round");
|
|
15
|
-
}
|
|
16
|
-
/** On-chain claimed bits own retry state; local transaction success logs do not. */
|
|
17
|
-
export function pendingRewardAllocations(round, manifest, leafDomain) {
|
|
18
|
-
assertRewardRoundMatchesManifest(round, manifest, leafDomain);
|
|
19
|
-
return manifest.allocations.filter((allocation) => !rewardIsClaimed(round, Number(allocation.index)));
|
|
20
|
-
}
|
|
21
|
-
//# sourceMappingURL=keeper.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"keeper.js","sourceRoot":"","sources":["../../src/rewards/keeper.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAW7C;;;;GAIG;AACH,MAAM,UAAU,gCAAgC,CAC9C,KAAsB,EACtB,QAAwB,EACxB,UAA4B;IAE5B,sBAAsB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IAC7C,IACE,KAAK,CAAC,OAAO,KAAK,QAAQ,CAAC,OAAO;QAClC,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;QACxC,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI;QAC5B,KAAK,CAAC,SAAS,KAAK,QAAQ,CAAC,WAAW,CAAC,MAAM;QAE/C,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;AAC5D,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,wBAAwB,CACtC,KAA0D,EAC1D,QAAwB,EACxB,UAA4B;IAE5B,gCAAgC,CAAC,KAAK,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;IAC9D,OAAO,QAAQ,CAAC,WAAW,CAAC,MAAM,CAChC,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAClE,CAAC;AACJ,CAAC"}
|
package/dist/rewards/state.d.ts
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import type { ClientWithCoreApi } from "@mysten/sui/client";
|
|
2
|
-
import type { SharedObjectReference } from "../sui.ts";
|
|
3
|
-
/** BCS layout of `blast_fun_migrators::blast_holder_rewards::Round<Meme, Quote>`. */
|
|
4
|
-
export declare const rewardRoundBcs: import("@mysten/sui/bcs").BcsStruct<{
|
|
5
|
-
id: import("@mysten/sui/bcs").BcsStruct<{
|
|
6
|
-
id: import("@mysten/sui/bcs").BcsStruct<{
|
|
7
|
-
bytes: import("@mysten/sui/bcs").BcsType<string, string | Uint8Array<ArrayBufferLike>, "bytes[32]">;
|
|
8
|
-
}, string>;
|
|
9
|
-
}, string>;
|
|
10
|
-
vault: import("@mysten/sui/bcs").BcsStruct<{
|
|
11
|
-
bytes: import("@mysten/sui/bcs").BcsType<string, string | Uint8Array<ArrayBufferLike>, "bytes[32]">;
|
|
12
|
-
}, string>;
|
|
13
|
-
number: import("@mysten/sui/bcs").BcsType<string, string | number | bigint, "u64">;
|
|
14
|
-
root: import("@mysten/sui/bcs").BcsType<number[], Iterable<number> & {
|
|
15
|
-
length: number;
|
|
16
|
-
}, string>;
|
|
17
|
-
leaf_count: import("@mysten/sui/bcs").BcsType<string, string | number | bigint, "u64">;
|
|
18
|
-
claimed: import("@mysten/sui/bcs").BcsType<string[], Iterable<string | number | bigint> & {
|
|
19
|
-
length: number;
|
|
20
|
-
}, string>;
|
|
21
|
-
meme: import("@mysten/sui/bcs").BcsStruct<{
|
|
22
|
-
value: import("@mysten/sui/bcs").BcsType<string, string | number | bigint, "u64">;
|
|
23
|
-
}, string>;
|
|
24
|
-
quote: import("@mysten/sui/bcs").BcsStruct<{
|
|
25
|
-
value: import("@mysten/sui/bcs").BcsType<string, string | number | bigint, "u64">;
|
|
26
|
-
}, string>;
|
|
27
|
-
}, string>;
|
|
28
|
-
export type RewardRoundObject = SharedObjectReference<true> & {
|
|
29
|
-
type: string;
|
|
30
|
-
content: Uint8Array;
|
|
31
|
-
};
|
|
32
|
-
/**
|
|
33
|
-
* Decodes one shared holder-reward round published from an LP vault. Its
|
|
34
|
-
* checkpoints and manifest digest are in its `RoundPublished` event.
|
|
35
|
-
*/
|
|
36
|
-
export declare function decodeRewardRound(object: RewardRoundObject, migratorsOriginalPackageId: string): {
|
|
37
|
-
objectId: string;
|
|
38
|
-
initialSharedVersion: number | string;
|
|
39
|
-
mutable: true;
|
|
40
|
-
type: string;
|
|
41
|
-
content: Uint8Array;
|
|
42
|
-
memeType: string;
|
|
43
|
-
quoteType: string;
|
|
44
|
-
vaultId: string;
|
|
45
|
-
number: bigint;
|
|
46
|
-
root: string;
|
|
47
|
-
leafCount: number;
|
|
48
|
-
claimed: bigint[];
|
|
49
|
-
memeAmount: bigint;
|
|
50
|
-
quoteAmount: bigint;
|
|
51
|
-
};
|
|
52
|
-
export type RewardRoundState = ReturnType<typeof decodeRewardRound>;
|
|
53
|
-
export declare function rewardIsClaimed(round: Pick<RewardRoundState, "leafCount" | "claimed">, index: number): boolean;
|
|
54
|
-
export declare function getRewardRound(client: ClientWithCoreApi, objectId: string, migratorsOriginalPackageId: string): Promise<RewardRoundState>;
|
|
55
|
-
//# sourceMappingURL=state.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/rewards/state.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAS5D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAGvD,qFAAqF;AACrF,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;UASzB,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,qBAAqB,CAAC,IAAI,CAAC,GAAG;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,UAAU,CAAC;CACrB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,iBAAiB,EACzB,0BAA0B,EAAE,MAAM;;;;UAV5B,MAAM;aACH,UAAU;;;;;;;;;;EAmDpB;AACD,MAAM,MAAM,gBAAgB,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAEpE,wBAAgB,eAAe,CAC7B,KAAK,EAAE,IAAI,CAAC,gBAAgB,EAAE,WAAW,GAAG,SAAS,CAAC,EACtD,KAAK,EAAE,MAAM,GACZ,OAAO,CAKT;AAED,wBAAsB,cAAc,CAClC,MAAM,EAAE,iBAAiB,EACzB,QAAQ,EAAE,MAAM,EAChB,0BAA0B,EAAE,MAAM,GACjC,OAAO,CAAC,gBAAgB,CAAC,CAiB3B"}
|
package/dist/rewards/state.js
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import { bcs } from "@mysten/sui/bcs";
|
|
2
|
-
import { normalizeStructTag, normalizeSuiAddress, parseStructTag, toHex, } from "@mysten/sui/utils";
|
|
3
|
-
import { itemAt } from "../arrays.js";
|
|
4
|
-
import { suiBalanceBcs, suiIdBcs, suiUidBcs } from "../bcs.js";
|
|
5
|
-
import { MAX_REWARD_LEAVES, rewardAddress } from "./allocations.js";
|
|
6
|
-
/** BCS layout of `blast_fun_migrators::blast_holder_rewards::Round<Meme, Quote>`. */
|
|
7
|
-
export const rewardRoundBcs = bcs.struct("Round", {
|
|
8
|
-
id: suiUidBcs,
|
|
9
|
-
vault: suiIdBcs,
|
|
10
|
-
number: bcs.u64(),
|
|
11
|
-
root: bcs.vector(bcs.u8()),
|
|
12
|
-
leaf_count: bcs.u64(),
|
|
13
|
-
claimed: bcs.vector(bcs.u256()),
|
|
14
|
-
meme: suiBalanceBcs,
|
|
15
|
-
quote: suiBalanceBcs,
|
|
16
|
-
});
|
|
17
|
-
/**
|
|
18
|
-
* Decodes one shared holder-reward round published from an LP vault. Its
|
|
19
|
-
* checkpoints and manifest digest are in its `RoundPublished` event.
|
|
20
|
-
*/
|
|
21
|
-
export function decodeRewardRound(object, migratorsOriginalPackageId) {
|
|
22
|
-
const tag = parseStructTag(object.type);
|
|
23
|
-
const [memeType, quoteType, ...extra] = tag.typeParams;
|
|
24
|
-
if (normalizeSuiAddress(tag.address) !==
|
|
25
|
-
rewardAddress(migratorsOriginalPackageId) ||
|
|
26
|
-
tag.module !== "blast_holder_rewards" ||
|
|
27
|
-
tag.name !== "Round" ||
|
|
28
|
-
memeType === undefined ||
|
|
29
|
-
quoteType === undefined ||
|
|
30
|
-
extra.length > 0 ||
|
|
31
|
-
object.mutable !== true) {
|
|
32
|
-
throw new Error("invalid holder-reward round type");
|
|
33
|
-
}
|
|
34
|
-
const decoded = rewardRoundBcs.parse(object.content);
|
|
35
|
-
if (rewardAddress(object.objectId) !== rewardAddress(decoded.id.id.bytes)) {
|
|
36
|
-
throw new Error("object UID mismatch");
|
|
37
|
-
}
|
|
38
|
-
const leafCount = Number(decoded.leaf_count);
|
|
39
|
-
if (!Number.isInteger(leafCount) ||
|
|
40
|
-
leafCount < 1 ||
|
|
41
|
-
leafCount > MAX_REWARD_LEAVES ||
|
|
42
|
-
decoded.claimed.length !== Math.ceil(leafCount / 256) ||
|
|
43
|
-
decoded.root.length !== 32) {
|
|
44
|
-
throw new Error("invalid round bounds");
|
|
45
|
-
}
|
|
46
|
-
return {
|
|
47
|
-
...object,
|
|
48
|
-
memeType: normalizeStructTag(memeType),
|
|
49
|
-
quoteType: normalizeStructTag(quoteType),
|
|
50
|
-
vaultId: rewardAddress(decoded.vault.bytes),
|
|
51
|
-
number: BigInt(decoded.number),
|
|
52
|
-
root: toHex(Uint8Array.from(decoded.root)),
|
|
53
|
-
leafCount,
|
|
54
|
-
claimed: decoded.claimed.map(BigInt),
|
|
55
|
-
memeAmount: BigInt(decoded.meme.value),
|
|
56
|
-
quoteAmount: BigInt(decoded.quote.value),
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
export function rewardIsClaimed(round, index) {
|
|
60
|
-
if (!Number.isSafeInteger(index) || index < 0 || index >= round.leafCount)
|
|
61
|
-
throw new RangeError("claim index out of bounds");
|
|
62
|
-
const word = itemAt(round.claimed, Math.floor(index / 256));
|
|
63
|
-
return (word & (1n << BigInt(index % 256))) !== 0n;
|
|
64
|
-
}
|
|
65
|
-
export async function getRewardRound(client, objectId, migratorsOriginalPackageId) {
|
|
66
|
-
const { object } = await client.core.getObject({
|
|
67
|
-
objectId: rewardAddress(objectId),
|
|
68
|
-
include: { content: true },
|
|
69
|
-
});
|
|
70
|
-
if (object.owner.$kind !== "Shared")
|
|
71
|
-
throw new Error("holder-reward round must be shared");
|
|
72
|
-
return decodeRewardRound({
|
|
73
|
-
objectId: object.objectId,
|
|
74
|
-
type: object.type,
|
|
75
|
-
content: object.content,
|
|
76
|
-
mutable: true,
|
|
77
|
-
initialSharedVersion: object.owner.Shared.initialSharedVersion,
|
|
78
|
-
}, migratorsOriginalPackageId);
|
|
79
|
-
}
|
|
80
|
-
//# sourceMappingURL=state.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/rewards/state.ts"],"names":[],"mappings":"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"}
|
package/dist/timelock.d.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { BcsType } from "@mysten/sui/bcs";
|
|
2
|
-
/**
|
|
3
|
-
* Mirrors `blast_fun_timelock::Timelocked<T>`: `before` until `atMs`, then
|
|
4
|
-
* `after`. `after` is the scheduled value; `delayMs` is fixed at creation.
|
|
5
|
-
*/
|
|
6
|
-
export type Timelocked<T> = {
|
|
7
|
-
before: T;
|
|
8
|
-
after: T;
|
|
9
|
-
atMs: bigint;
|
|
10
|
-
delayMs: bigint;
|
|
11
|
-
};
|
|
12
|
-
export declare function timelockedBcs<T>(value: BcsType<T, T>): BcsType<Timelocked<T>, Timelocked<T>, string>;
|
|
13
|
-
/** Mirrors `blast_fun_timelock::value`: the value in force at `nowMs`. */
|
|
14
|
-
export declare function timelockedValue<T>(timelocked: Timelocked<T>, nowMs: bigint): T;
|
|
15
|
-
//# sourceMappingURL=timelock.d.ts.map
|
package/dist/timelock.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"timelock.d.ts","sourceRoot":"","sources":["../src/timelock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAK/C;;;GAGG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI;IAC1B,MAAM,EAAE,CAAC,CAAC;IACV,KAAK,EAAE,CAAC,CAAC;IACT,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,wBAAgB,aAAa,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,iDAsBpD;AAED,0EAA0E;AAC1E,wBAAgB,eAAe,CAAC,CAAC,EAC/B,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,EACzB,KAAK,EAAE,MAAM,GACZ,CAAC,CAEH"}
|
package/dist/timelock.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { bcs } from "@mysten/sui/bcs";
|
|
2
|
-
import { u64Bcs } from "./bcs.js";
|
|
3
|
-
export function timelockedBcs(value) {
|
|
4
|
-
return bcs
|
|
5
|
-
.struct("Timelocked", {
|
|
6
|
-
before: value,
|
|
7
|
-
after: value,
|
|
8
|
-
at_ms: u64Bcs,
|
|
9
|
-
delay_ms: u64Bcs,
|
|
10
|
-
})
|
|
11
|
-
.transform({
|
|
12
|
-
input: (timelocked) => ({
|
|
13
|
-
before: timelocked.before,
|
|
14
|
-
after: timelocked.after,
|
|
15
|
-
at_ms: timelocked.atMs,
|
|
16
|
-
delay_ms: timelocked.delayMs,
|
|
17
|
-
}),
|
|
18
|
-
output: (timelocked) => ({
|
|
19
|
-
before: timelocked.before,
|
|
20
|
-
after: timelocked.after,
|
|
21
|
-
atMs: timelocked.at_ms,
|
|
22
|
-
delayMs: timelocked.delay_ms,
|
|
23
|
-
}),
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
/** Mirrors `blast_fun_timelock::value`: the value in force at `nowMs`. */
|
|
27
|
-
export function timelockedValue(timelocked, nowMs) {
|
|
28
|
-
return nowMs >= timelocked.atMs ? timelocked.after : timelocked.before;
|
|
29
|
-
}
|
|
30
|
-
//# sourceMappingURL=timelock.js.map
|
package/dist/timelock.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"timelock.js","sourceRoot":"","sources":["../src/timelock.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAEtC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAalC,MAAM,UAAU,aAAa,CAAI,KAAoB;IACnD,OAAO,GAAG;SACP,MAAM,CAAC,YAAY,EAAE;QACpB,MAAM,EAAE,KAAK;QACb,KAAK,EAAE,KAAK;QACZ,KAAK,EAAE,MAAM;QACb,QAAQ,EAAE,MAAM;KACjB,CAAC;SACD,SAAS,CAAC;QACT,KAAK,EAAE,CAAC,UAAyB,EAAE,EAAE,CAAC,CAAC;YACrC,MAAM,EAAE,UAAU,CAAC,MAAM;YACzB,KAAK,EAAE,UAAU,CAAC,KAAK;YACvB,KAAK,EAAE,UAAU,CAAC,IAAI;YACtB,QAAQ,EAAE,UAAU,CAAC,OAAO;SAC7B,CAAC;QACF,MAAM,EAAE,CAAC,UAAU,EAAiB,EAAE,CAAC,CAAC;YACtC,MAAM,EAAE,UAAU,CAAC,MAAM;YACzB,KAAK,EAAE,UAAU,CAAC,KAAK;YACvB,IAAI,EAAE,UAAU,CAAC,KAAK;YACtB,OAAO,EAAE,UAAU,CAAC,QAAQ;SAC7B,CAAC;KACH,CAAC,CAAC;AACP,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,eAAe,CAC7B,UAAyB,EACzB,KAAa;IAEb,OAAO,KAAK,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC;AACzE,CAAC"}
|
package/src/rewards/keeper.ts
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import type { RewardLeafDomain, RewardManifest } from "./allocations.ts";
|
|
2
|
-
import { validateRewardManifest } from "./allocations.ts";
|
|
3
|
-
import type { RewardRoundState } from "./state.ts";
|
|
4
|
-
import { rewardIsClaimed } from "./state.ts";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* What a `blast_holder_rewards::Round` object commits to. Its checkpoint window
|
|
8
|
-
* and manifest digest are only in the `RoundPublished` event.
|
|
9
|
-
*/
|
|
10
|
-
type RoundCommitment = Pick<
|
|
11
|
-
RewardRoundState,
|
|
12
|
-
"vaultId" | "number" | "root" | "leafCount"
|
|
13
|
-
>;
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* A relayer must compare the public artifact with authoritative chain state
|
|
17
|
-
* before paying. The root commits every leaf; the round object keeps no
|
|
18
|
-
* checkpoints or manifest digest (its `RoundPublished` event does).
|
|
19
|
-
*/
|
|
20
|
-
export function assertRewardRoundMatchesManifest(
|
|
21
|
-
round: RoundCommitment,
|
|
22
|
-
manifest: RewardManifest,
|
|
23
|
-
leafDomain: RewardLeafDomain,
|
|
24
|
-
): void {
|
|
25
|
-
validateRewardManifest(manifest, leafDomain);
|
|
26
|
-
if (
|
|
27
|
-
round.vaultId !== manifest.vaultId ||
|
|
28
|
-
round.number !== BigInt(manifest.number) ||
|
|
29
|
-
round.root !== manifest.root ||
|
|
30
|
-
round.leafCount !== manifest.allocations.length
|
|
31
|
-
)
|
|
32
|
-
throw new Error("manifest does not match funded round");
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/** On-chain claimed bits own retry state; local transaction success logs do not. */
|
|
36
|
-
export function pendingRewardAllocations(
|
|
37
|
-
round: RoundCommitment & Pick<RewardRoundState, "claimed">,
|
|
38
|
-
manifest: RewardManifest,
|
|
39
|
-
leafDomain: RewardLeafDomain,
|
|
40
|
-
) {
|
|
41
|
-
assertRewardRoundMatchesManifest(round, manifest, leafDomain);
|
|
42
|
-
return manifest.allocations.filter(
|
|
43
|
-
(allocation) => !rewardIsClaimed(round, Number(allocation.index)),
|
|
44
|
-
);
|
|
45
|
-
}
|
package/src/rewards/state.ts
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import { bcs } from "@mysten/sui/bcs";
|
|
2
|
-
import type { ClientWithCoreApi } from "@mysten/sui/client";
|
|
3
|
-
import {
|
|
4
|
-
normalizeStructTag,
|
|
5
|
-
normalizeSuiAddress,
|
|
6
|
-
parseStructTag,
|
|
7
|
-
toHex,
|
|
8
|
-
} from "@mysten/sui/utils";
|
|
9
|
-
import { itemAt } from "../arrays.ts";
|
|
10
|
-
import { suiBalanceBcs, suiIdBcs, suiUidBcs } from "../bcs.ts";
|
|
11
|
-
import type { SharedObjectReference } from "../sui.ts";
|
|
12
|
-
import { MAX_REWARD_LEAVES, rewardAddress } from "./allocations.ts";
|
|
13
|
-
|
|
14
|
-
/** BCS layout of `blast_fun_migrators::blast_holder_rewards::Round<Meme, Quote>`. */
|
|
15
|
-
export const rewardRoundBcs = bcs.struct("Round", {
|
|
16
|
-
id: suiUidBcs,
|
|
17
|
-
vault: suiIdBcs,
|
|
18
|
-
number: bcs.u64(),
|
|
19
|
-
root: bcs.vector(bcs.u8()),
|
|
20
|
-
leaf_count: bcs.u64(),
|
|
21
|
-
claimed: bcs.vector(bcs.u256()),
|
|
22
|
-
meme: suiBalanceBcs,
|
|
23
|
-
quote: suiBalanceBcs,
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
export type RewardRoundObject = SharedObjectReference<true> & {
|
|
27
|
-
type: string;
|
|
28
|
-
content: Uint8Array;
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Decodes one shared holder-reward round published from an LP vault. Its
|
|
33
|
-
* checkpoints and manifest digest are in its `RoundPublished` event.
|
|
34
|
-
*/
|
|
35
|
-
export function decodeRewardRound(
|
|
36
|
-
object: RewardRoundObject,
|
|
37
|
-
migratorsOriginalPackageId: string,
|
|
38
|
-
) {
|
|
39
|
-
const tag = parseStructTag(object.type);
|
|
40
|
-
const [memeType, quoteType, ...extra] = tag.typeParams;
|
|
41
|
-
if (
|
|
42
|
-
normalizeSuiAddress(tag.address) !==
|
|
43
|
-
rewardAddress(migratorsOriginalPackageId) ||
|
|
44
|
-
tag.module !== "blast_holder_rewards" ||
|
|
45
|
-
tag.name !== "Round" ||
|
|
46
|
-
memeType === undefined ||
|
|
47
|
-
quoteType === undefined ||
|
|
48
|
-
extra.length > 0 ||
|
|
49
|
-
object.mutable !== true
|
|
50
|
-
) {
|
|
51
|
-
throw new Error("invalid holder-reward round type");
|
|
52
|
-
}
|
|
53
|
-
const decoded = rewardRoundBcs.parse(object.content);
|
|
54
|
-
if (rewardAddress(object.objectId) !== rewardAddress(decoded.id.id.bytes)) {
|
|
55
|
-
throw new Error("object UID mismatch");
|
|
56
|
-
}
|
|
57
|
-
const leafCount = Number(decoded.leaf_count);
|
|
58
|
-
if (
|
|
59
|
-
!Number.isInteger(leafCount) ||
|
|
60
|
-
leafCount < 1 ||
|
|
61
|
-
leafCount > MAX_REWARD_LEAVES ||
|
|
62
|
-
decoded.claimed.length !== Math.ceil(leafCount / 256) ||
|
|
63
|
-
decoded.root.length !== 32
|
|
64
|
-
) {
|
|
65
|
-
throw new Error("invalid round bounds");
|
|
66
|
-
}
|
|
67
|
-
return {
|
|
68
|
-
...object,
|
|
69
|
-
memeType: normalizeStructTag(memeType),
|
|
70
|
-
quoteType: normalizeStructTag(quoteType),
|
|
71
|
-
vaultId: rewardAddress(decoded.vault.bytes),
|
|
72
|
-
number: BigInt(decoded.number),
|
|
73
|
-
root: toHex(Uint8Array.from(decoded.root)),
|
|
74
|
-
leafCount,
|
|
75
|
-
claimed: decoded.claimed.map(BigInt),
|
|
76
|
-
memeAmount: BigInt(decoded.meme.value),
|
|
77
|
-
quoteAmount: BigInt(decoded.quote.value),
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
export type RewardRoundState = ReturnType<typeof decodeRewardRound>;
|
|
81
|
-
|
|
82
|
-
export function rewardIsClaimed(
|
|
83
|
-
round: Pick<RewardRoundState, "leafCount" | "claimed">,
|
|
84
|
-
index: number,
|
|
85
|
-
): boolean {
|
|
86
|
-
if (!Number.isSafeInteger(index) || index < 0 || index >= round.leafCount)
|
|
87
|
-
throw new RangeError("claim index out of bounds");
|
|
88
|
-
const word = itemAt(round.claimed, Math.floor(index / 256));
|
|
89
|
-
return (word & (1n << BigInt(index % 256))) !== 0n;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
export async function getRewardRound(
|
|
93
|
-
client: ClientWithCoreApi,
|
|
94
|
-
objectId: string,
|
|
95
|
-
migratorsOriginalPackageId: string,
|
|
96
|
-
): Promise<RewardRoundState> {
|
|
97
|
-
const { object } = await client.core.getObject({
|
|
98
|
-
objectId: rewardAddress(objectId),
|
|
99
|
-
include: { content: true },
|
|
100
|
-
});
|
|
101
|
-
if (object.owner.$kind !== "Shared")
|
|
102
|
-
throw new Error("holder-reward round must be shared");
|
|
103
|
-
return decodeRewardRound(
|
|
104
|
-
{
|
|
105
|
-
objectId: object.objectId,
|
|
106
|
-
type: object.type,
|
|
107
|
-
content: object.content,
|
|
108
|
-
mutable: true,
|
|
109
|
-
initialSharedVersion: object.owner.Shared.initialSharedVersion,
|
|
110
|
-
},
|
|
111
|
-
migratorsOriginalPackageId,
|
|
112
|
-
);
|
|
113
|
-
}
|
package/src/timelock.ts
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import type { BcsType } from "@mysten/sui/bcs";
|
|
2
|
-
import { bcs } from "@mysten/sui/bcs";
|
|
3
|
-
|
|
4
|
-
import { u64Bcs } from "./bcs.ts";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Mirrors `blast_fun_timelock::Timelocked<T>`: `before` until `atMs`, then
|
|
8
|
-
* `after`. `after` is the scheduled value; `delayMs` is fixed at creation.
|
|
9
|
-
*/
|
|
10
|
-
export type Timelocked<T> = {
|
|
11
|
-
before: T;
|
|
12
|
-
after: T;
|
|
13
|
-
atMs: bigint;
|
|
14
|
-
delayMs: bigint;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
export function timelockedBcs<T>(value: BcsType<T, T>) {
|
|
18
|
-
return bcs
|
|
19
|
-
.struct("Timelocked", {
|
|
20
|
-
before: value,
|
|
21
|
-
after: value,
|
|
22
|
-
at_ms: u64Bcs,
|
|
23
|
-
delay_ms: u64Bcs,
|
|
24
|
-
})
|
|
25
|
-
.transform({
|
|
26
|
-
input: (timelocked: Timelocked<T>) => ({
|
|
27
|
-
before: timelocked.before,
|
|
28
|
-
after: timelocked.after,
|
|
29
|
-
at_ms: timelocked.atMs,
|
|
30
|
-
delay_ms: timelocked.delayMs,
|
|
31
|
-
}),
|
|
32
|
-
output: (timelocked): Timelocked<T> => ({
|
|
33
|
-
before: timelocked.before,
|
|
34
|
-
after: timelocked.after,
|
|
35
|
-
atMs: timelocked.at_ms,
|
|
36
|
-
delayMs: timelocked.delay_ms,
|
|
37
|
-
}),
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/** Mirrors `blast_fun_timelock::value`: the value in force at `nowMs`. */
|
|
42
|
-
export function timelockedValue<T>(
|
|
43
|
-
timelocked: Timelocked<T>,
|
|
44
|
-
nowMs: bigint,
|
|
45
|
-
): T {
|
|
46
|
-
return nowMs >= timelocked.atMs ? timelocked.after : timelocked.before;
|
|
47
|
-
}
|