@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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration.js","sourceRoot":"","sources":["../src/migration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC3D,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAU7C,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG;KACjC,IAAI,CAAC,gBAAgB,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;KACvD,SAAS,CAAC;IACT,KAAK,EAAE,CAAC,MAAsB,EAAE,EAAE,CAChC,MAAM,KAAK,UAAU;QACnB,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAa,EAAE;QAC7B,CAAC,CAAC,EAAE,KAAK,EAAE,IAAa,EAAE;IAC9B,MAAM,EAAE,CAAC,MAAM,EAAkB,EAAE,CAAC,MAAM,CAAC,KAAK;CACjD,CAAC,CAAC;AAiBL,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG;KAC7B,MAAM,CAAC,YAAY,EAAE;IACpB,MAAM,EAAE,cAAc;IACtB,eAAe,EAAE,eAAe;IAChC,SAAS,EAAE,WAAW;IACtB,iBAAiB,EAAE,MAAM;IACzB,kBAAkB,EAAE,MAAM;IAC1B,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,cAAc,CAAC;IACtC,SAAS,EAAE,iBAAiB;CAC7B,CAAC;KACD,SAAS,CAAC;IACT,KAAK,EAAE,CAAC,KAAiB,EAAE,EAAE,CAAC,CAAC;QAC7B,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,eAAe,EAAE,KAAK,CAAC,cAAc;QACrC,SAAS,EAAE,KAAK,CAAC,QAAQ;QACzB,iBAAiB,EAAE,KAAK,CAAC,eAAe;QACxC,kBAAkB,EAAE,KAAK,CAAC,gBAAgB;QAC1C,UAAU,EAAE,KAAK,CAAC,SAAS;QAC3B,SAAS,EAAE,KAAK,CAAC,SAAS;KAC3B,CAAC;IACF,MAAM,EAAE,CAAC,KAAK,EAAc,EAAE,CAAC,CAAC;QAC9B,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,cAAc,EAAE,KAAK,CAAC,eAAe;QACrC,QAAQ,EAAE,KAAK,CAAC,SAAS;QACzB,eAAe,EAAE,KAAK,CAAC,iBAAiB;QACxC,gBAAgB,EAAE,KAAK,CAAC,kBAAkB;QAC1C,SAAS,EAAE,KAAK,CAAC,UAAU;QAC3B,SAAS,EAAE,KAAK,CAAC,SAAS;KAC3B,CAAC;CACH,CAAC,CAAC"}
|
package/dist/payout.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `blast_core::payout::VestingTerms`: `periods` equal steps of
|
|
3
|
+
* `periodDurationMs` each, the first available `cliffDelayMs` after the
|
|
4
|
+
* payout.
|
|
5
|
+
*/
|
|
6
|
+
export type VestingTerms = {
|
|
7
|
+
cliffDelayMs: bigint;
|
|
8
|
+
periodDurationMs: bigint;
|
|
9
|
+
periods: bigint;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* `blast_core::payout::Recipient`: where a payout goes, paid outright when
|
|
13
|
+
* `vestingTerms` is null and locked under them otherwise.
|
|
14
|
+
*/
|
|
15
|
+
export type Recipient = {
|
|
16
|
+
destination: string;
|
|
17
|
+
vestingTerms: VestingTerms | null;
|
|
18
|
+
};
|
|
19
|
+
export declare const vestingTermsBcs: import("@mysten/sui/bcs").BcsType<VestingTerms, VestingTerms, string>;
|
|
20
|
+
export declare const recipientBcs: import("@mysten/sui/bcs").BcsType<Recipient, Recipient, string>;
|
|
21
|
+
//# sourceMappingURL=payout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payout.d.ts","sourceRoot":"","sources":["../src/payout.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,YAAY,GAAG,IAAI,CAAC;CACnC,CAAC;AAEF,eAAO,MAAM,eAAe,uEAiBxB,CAAC;AAEL,eAAO,MAAM,YAAY,iEAcrB,CAAC"}
|
package/dist/payout.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { bcs } from "@mysten/sui/bcs";
|
|
2
|
+
import { addressBcs, u64Bcs } from "./bcs.js";
|
|
3
|
+
export const vestingTermsBcs = bcs
|
|
4
|
+
.struct("VestingTerms", {
|
|
5
|
+
cliff_delay_ms: u64Bcs,
|
|
6
|
+
period_duration_ms: u64Bcs,
|
|
7
|
+
periods: u64Bcs,
|
|
8
|
+
})
|
|
9
|
+
.transform({
|
|
10
|
+
input: (terms) => ({
|
|
11
|
+
cliff_delay_ms: terms.cliffDelayMs,
|
|
12
|
+
period_duration_ms: terms.periodDurationMs,
|
|
13
|
+
periods: terms.periods,
|
|
14
|
+
}),
|
|
15
|
+
output: (terms) => ({
|
|
16
|
+
cliffDelayMs: terms.cliff_delay_ms,
|
|
17
|
+
periodDurationMs: terms.period_duration_ms,
|
|
18
|
+
periods: terms.periods,
|
|
19
|
+
}),
|
|
20
|
+
});
|
|
21
|
+
export const recipientBcs = bcs
|
|
22
|
+
.struct("Recipient", {
|
|
23
|
+
destination: addressBcs,
|
|
24
|
+
vesting_terms: bcs.option(vestingTermsBcs),
|
|
25
|
+
})
|
|
26
|
+
.transform({
|
|
27
|
+
input: (recipient) => ({
|
|
28
|
+
destination: recipient.destination,
|
|
29
|
+
vesting_terms: recipient.vestingTerms,
|
|
30
|
+
}),
|
|
31
|
+
output: (recipient) => ({
|
|
32
|
+
destination: recipient.destination,
|
|
33
|
+
vestingTerms: recipient.vesting_terms,
|
|
34
|
+
}),
|
|
35
|
+
});
|
|
36
|
+
//# sourceMappingURL=payout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payout.js","sourceRoot":"","sources":["../src/payout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAsB9C,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG;KAC/B,MAAM,CAAC,cAAc,EAAE;IACtB,cAAc,EAAE,MAAM;IACtB,kBAAkB,EAAE,MAAM;IAC1B,OAAO,EAAE,MAAM;CAChB,CAAC;KACD,SAAS,CAAC;IACT,KAAK,EAAE,CAAC,KAAmB,EAAE,EAAE,CAAC,CAAC;QAC/B,cAAc,EAAE,KAAK,CAAC,YAAY;QAClC,kBAAkB,EAAE,KAAK,CAAC,gBAAgB;QAC1C,OAAO,EAAE,KAAK,CAAC,OAAO;KACvB,CAAC;IACF,MAAM,EAAE,CAAC,KAAK,EAAgB,EAAE,CAAC,CAAC;QAChC,YAAY,EAAE,KAAK,CAAC,cAAc;QAClC,gBAAgB,EAAE,KAAK,CAAC,kBAAkB;QAC1C,OAAO,EAAE,KAAK,CAAC,OAAO;KACvB,CAAC;CACH,CAAC,CAAC;AAEL,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG;KAC5B,MAAM,CAAC,WAAW,EAAE;IACnB,WAAW,EAAE,UAAU;IACvB,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,eAAe,CAAC;CAC3C,CAAC;KACD,SAAS,CAAC;IACT,KAAK,EAAE,CAAC,SAAoB,EAAE,EAAE,CAAC,CAAC;QAChC,WAAW,EAAE,SAAS,CAAC,WAAW;QAClC,aAAa,EAAE,SAAS,CAAC,YAAY;KACtC,CAAC;IACF,MAAM,EAAE,CAAC,SAAS,EAAa,EAAE,CAAC,CAAC;QACjC,WAAW,EAAE,SAAS,CAAC,WAAW;QAClC,YAAY,EAAE,SAAS,CAAC,aAAa;KACtC,CAAC;CACH,CAAC,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { SuiClientTypes } from "@mysten/sui/client";
|
|
2
|
+
import type { SuiEventPosition } from "./events.ts";
|
|
3
|
+
/**
|
|
4
|
+
* `blast_core::protocol_fees::Ledger<Meme, Quote>`: Blast's held fees of one
|
|
5
|
+
* launch, presale or vault. `packageWitness` is the original type of the
|
|
6
|
+
* package witness that created it; `partnerId` is fixed at creation.
|
|
7
|
+
*/
|
|
8
|
+
export declare const ledgerBcs: import("@mysten/sui/bcs").BcsType<Ledger, Ledger, string>;
|
|
9
|
+
export type Ledger = {
|
|
10
|
+
packageWitness: string;
|
|
11
|
+
origin: string;
|
|
12
|
+
partnerId: string | null;
|
|
13
|
+
meme: bigint;
|
|
14
|
+
quote: bigint;
|
|
15
|
+
sui: bigint;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Mirrors the amount `protocol_fees::take_cut` moves into the ledger from
|
|
19
|
+
* one fee of one asset: `ceil(amount * bps / 10,000)`; the fee keeps the rest.
|
|
20
|
+
*/
|
|
21
|
+
export declare function takeCut(amount: bigint, bps: bigint): bigint;
|
|
22
|
+
/** `blast_core::blast_core_events::ProtocolFeesPaid<Meme, Quote>`, in Move field order. */
|
|
23
|
+
export declare const protocolFeesPaidBcs: import("@mysten/sui/bcs").BcsStruct<{
|
|
24
|
+
package_witness: import("@mysten/sui/bcs").BcsType<string, string, string>;
|
|
25
|
+
origin: import("@mysten/sui/bcs").BcsType<string, string, string>;
|
|
26
|
+
treasury: import("@mysten/sui/bcs").BcsType<string, string, "bytes[32]">;
|
|
27
|
+
meme_amount: import("@mysten/sui/bcs").BcsType<bigint, bigint, "u64">;
|
|
28
|
+
quote_amount: import("@mysten/sui/bcs").BcsType<bigint, bigint, "u64">;
|
|
29
|
+
sui_amount: import("@mysten/sui/bcs").BcsType<bigint, bigint, "u64">;
|
|
30
|
+
partner_id: import("@mysten/sui/bcs").BcsType<string | null, string | null | undefined, `Option<${string}>`>;
|
|
31
|
+
partner_meme_amount: import("@mysten/sui/bcs").BcsType<bigint, bigint, "u64">;
|
|
32
|
+
partner_quote_amount: import("@mysten/sui/bcs").BcsType<bigint, bigint, "u64">;
|
|
33
|
+
partner_sui_amount: import("@mysten/sui/bcs").BcsType<bigint, bigint, "u64">;
|
|
34
|
+
}, string>;
|
|
35
|
+
export type ProtocolFeesPaid = ReturnType<typeof protocolFeesPaidBcs.parse>;
|
|
36
|
+
export type DecodedProtocolFeesPaid = {
|
|
37
|
+
source: "core";
|
|
38
|
+
kind: "ProtocolFeesPaid";
|
|
39
|
+
memeType: string;
|
|
40
|
+
quoteType: string;
|
|
41
|
+
payload: ProtocolFeesPaid;
|
|
42
|
+
sender: string;
|
|
43
|
+
position: SuiEventPosition;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Decodes one `<core>::blast_core_events::ProtocolFeesPaid<Meme, Quote>`.
|
|
47
|
+
* `payload.origin` is the launch, presale or vault whose ledger paid, and
|
|
48
|
+
* `payload.package_witness` the package that created the ledger.
|
|
49
|
+
*/
|
|
50
|
+
export declare function decodeProtocolFeesPaid(event: SuiClientTypes.EventEntry, core: {
|
|
51
|
+
originalPackageId: string;
|
|
52
|
+
}): DecodedProtocolFeesPaid;
|
|
53
|
+
/**
|
|
54
|
+
* Previews `protocol_fees::pay` / `pay_with_partner` over a decoded ledger:
|
|
55
|
+
* the bound partner's cut of each asset first (`partnerShareBps` of it,
|
|
56
|
+
* rounded down per asset as `blast_partners::pay`), Blast's treasury the
|
|
57
|
+
* rest. `partnerShareBps` is required exactly when the ledger names a
|
|
58
|
+
* partner. Null when the ledger is empty: the contract sends and emits
|
|
59
|
+
* nothing. Omits `package_witness`, `origin` and `treasury`, which the
|
|
60
|
+
* ledger and the treasury object carry.
|
|
61
|
+
*/
|
|
62
|
+
export declare function previewProtocolFeesPaid(ledger: Ledger, partnerShareBps: bigint | null): Pick<ProtocolFeesPaid, "meme_amount" | "quote_amount" | "sui_amount" | "partner_id" | "partner_meme_amount" | "partner_quote_amount" | "partner_sui_amount"> | null;
|
|
63
|
+
//# sourceMappingURL=protocol-fees.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol-fees.d.ts","sourceRoot":"","sources":["../src/protocol-fees.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAczD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAIpD;;;;GAIG;AACH,eAAO,MAAM,SAAS,2DA0BlB,CAAC;AAEL,MAAM,MAAM,MAAM,GAAG;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF;;;GAGG;AACH,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,2FAA2F;AAC3F,eAAO,MAAM,mBAAmB;;;;;;;;;;;UAW9B,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,KAAK,CAAC,CAAC;AAE5E,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,kBAAkB,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,gBAAgB,CAAC;CAC5B,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,cAAc,CAAC,UAAU,EAChC,IAAI,EAAE;IAAE,iBAAiB,EAAE,MAAM,CAAA;CAAE,GAClC,uBAAuB,CAsBzB;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,EACd,eAAe,EAAE,MAAM,GAAG,IAAI,GAC7B,IAAI,CACL,gBAAgB,EACd,aAAa,GACb,cAAc,GACd,YAAY,GACZ,YAAY,GACZ,qBAAqB,GACrB,sBAAsB,GACtB,oBAAoB,CACvB,GAAG,IAAI,CAyBP"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { bcs } from "@mysten/sui/bcs";
|
|
2
|
+
import { normalizeStructTag, normalizeSuiAddress, parseStructTag, } from "@mysten/sui/utils";
|
|
3
|
+
import { addressBcs, balanceBcs, moveTypeNameBcs, suiObjectIdBcs, u64Bcs, } from "./bcs.js";
|
|
4
|
+
import { applyBpsUp } from "./bps.js";
|
|
5
|
+
import { normalizeSuiEventPosition } from "./events.js";
|
|
6
|
+
import { BASIS_POINTS_DENOMINATOR, mulDivDown } from "./integers.js";
|
|
7
|
+
/**
|
|
8
|
+
* `blast_core::protocol_fees::Ledger<Meme, Quote>`: Blast's held fees of one
|
|
9
|
+
* launch, presale or vault. `packageWitness` is the original type of the
|
|
10
|
+
* package witness that created it; `partnerId` is fixed at creation.
|
|
11
|
+
*/
|
|
12
|
+
export const ledgerBcs = bcs
|
|
13
|
+
.struct("Ledger", {
|
|
14
|
+
package_witness: moveTypeNameBcs,
|
|
15
|
+
origin: suiObjectIdBcs,
|
|
16
|
+
partner_id: bcs.option(suiObjectIdBcs),
|
|
17
|
+
meme: balanceBcs,
|
|
18
|
+
quote: balanceBcs,
|
|
19
|
+
sui: balanceBcs,
|
|
20
|
+
})
|
|
21
|
+
.transform({
|
|
22
|
+
input: (ledger) => ({
|
|
23
|
+
package_witness: ledger.packageWitness,
|
|
24
|
+
origin: ledger.origin,
|
|
25
|
+
partner_id: ledger.partnerId,
|
|
26
|
+
meme: ledger.meme,
|
|
27
|
+
quote: ledger.quote,
|
|
28
|
+
sui: ledger.sui,
|
|
29
|
+
}),
|
|
30
|
+
output: (ledger) => ({
|
|
31
|
+
packageWitness: ledger.package_witness,
|
|
32
|
+
origin: ledger.origin,
|
|
33
|
+
partnerId: ledger.partner_id,
|
|
34
|
+
meme: ledger.meme,
|
|
35
|
+
quote: ledger.quote,
|
|
36
|
+
sui: ledger.sui,
|
|
37
|
+
}),
|
|
38
|
+
});
|
|
39
|
+
/**
|
|
40
|
+
* Mirrors the amount `protocol_fees::take_cut` moves into the ledger from
|
|
41
|
+
* one fee of one asset: `ceil(amount * bps / 10,000)`; the fee keeps the rest.
|
|
42
|
+
*/
|
|
43
|
+
export function takeCut(amount, bps) {
|
|
44
|
+
return applyBpsUp(amount, bps);
|
|
45
|
+
}
|
|
46
|
+
/** `blast_core::blast_core_events::ProtocolFeesPaid<Meme, Quote>`, in Move field order. */
|
|
47
|
+
export const protocolFeesPaidBcs = bcs.struct("ProtocolFeesPaid", {
|
|
48
|
+
package_witness: moveTypeNameBcs,
|
|
49
|
+
origin: suiObjectIdBcs,
|
|
50
|
+
treasury: addressBcs,
|
|
51
|
+
meme_amount: u64Bcs,
|
|
52
|
+
quote_amount: u64Bcs,
|
|
53
|
+
sui_amount: u64Bcs,
|
|
54
|
+
partner_id: bcs.option(suiObjectIdBcs),
|
|
55
|
+
partner_meme_amount: u64Bcs,
|
|
56
|
+
partner_quote_amount: u64Bcs,
|
|
57
|
+
partner_sui_amount: u64Bcs,
|
|
58
|
+
});
|
|
59
|
+
/**
|
|
60
|
+
* Decodes one `<core>::blast_core_events::ProtocolFeesPaid<Meme, Quote>`.
|
|
61
|
+
* `payload.origin` is the launch, presale or vault whose ledger paid, and
|
|
62
|
+
* `payload.package_witness` the package that created the ledger.
|
|
63
|
+
*/
|
|
64
|
+
export function decodeProtocolFeesPaid(event, core) {
|
|
65
|
+
const tag = parseStructTag(event.eventType);
|
|
66
|
+
const [meme, quote, ...extra] = tag.typeParams;
|
|
67
|
+
if (tag.address !== normalizeSuiAddress(core.originalPackageId) ||
|
|
68
|
+
tag.module !== "blast_core_events" ||
|
|
69
|
+
tag.name !== "ProtocolFeesPaid" ||
|
|
70
|
+
meme === undefined ||
|
|
71
|
+
quote === undefined ||
|
|
72
|
+
extra.length > 0) {
|
|
73
|
+
throw new TypeError(`unexpected core event type ${event.eventType}`);
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
source: "core",
|
|
77
|
+
kind: "ProtocolFeesPaid",
|
|
78
|
+
memeType: normalizeStructTag(meme),
|
|
79
|
+
quoteType: normalizeStructTag(quote),
|
|
80
|
+
payload: protocolFeesPaidBcs.parse(event.bcs),
|
|
81
|
+
sender: normalizeSuiAddress(event.sender),
|
|
82
|
+
position: normalizeSuiEventPosition(event),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Previews `protocol_fees::pay` / `pay_with_partner` over a decoded ledger:
|
|
87
|
+
* the bound partner's cut of each asset first (`partnerShareBps` of it,
|
|
88
|
+
* rounded down per asset as `blast_partners::pay`), Blast's treasury the
|
|
89
|
+
* rest. `partnerShareBps` is required exactly when the ledger names a
|
|
90
|
+
* partner. Null when the ledger is empty: the contract sends and emits
|
|
91
|
+
* nothing. Omits `package_witness`, `origin` and `treasury`, which the
|
|
92
|
+
* ledger and the treasury object carry.
|
|
93
|
+
*/
|
|
94
|
+
export function previewProtocolFeesPaid(ledger, partnerShareBps) {
|
|
95
|
+
if ((ledger.partnerId === null) !== (partnerShareBps === null)) {
|
|
96
|
+
throw new TypeError("a partner share is required exactly when the ledger names a partner");
|
|
97
|
+
}
|
|
98
|
+
if (ledger.meme === 0n && ledger.quote === 0n && ledger.sui === 0n) {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
const cut = (amount) => partnerShareBps === null
|
|
102
|
+
? 0n
|
|
103
|
+
: mulDivDown(amount, partnerShareBps, BASIS_POINTS_DENOMINATOR);
|
|
104
|
+
const partnerMeme = cut(ledger.meme);
|
|
105
|
+
const partnerQuote = cut(ledger.quote);
|
|
106
|
+
const partnerSui = cut(ledger.sui);
|
|
107
|
+
return {
|
|
108
|
+
meme_amount: ledger.meme - partnerMeme,
|
|
109
|
+
quote_amount: ledger.quote - partnerQuote,
|
|
110
|
+
sui_amount: ledger.sui - partnerSui,
|
|
111
|
+
partner_id: ledger.partnerId,
|
|
112
|
+
partner_meme_amount: partnerMeme,
|
|
113
|
+
partner_quote_amount: partnerQuote,
|
|
114
|
+
partner_sui_amount: partnerSui,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=protocol-fees.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol-fees.js","sourceRoot":"","sources":["../src/protocol-fees.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,7 +16,7 @@ export type RewardProof = {
|
|
|
16
16
|
proof: string[];
|
|
17
17
|
};
|
|
18
18
|
export type RewardManifest = {
|
|
19
|
-
version:
|
|
19
|
+
version: 2;
|
|
20
20
|
vaultId: string;
|
|
21
21
|
number: string;
|
|
22
22
|
startCheckpoint: string;
|
|
@@ -30,7 +30,6 @@ export type RewardManifest = {
|
|
|
30
30
|
/** Complete commitment after durable paged construction; it does not contain all proofs in memory. */
|
|
31
31
|
export type RewardManifestSummary = Omit<RewardManifest, "allocations"> & {
|
|
32
32
|
leafCount: number;
|
|
33
|
-
leafDomain: RewardLeafDomain;
|
|
34
33
|
};
|
|
35
34
|
/**
|
|
36
35
|
* One immutable, canonically ordered allocation snapshot and its durable output namespace.
|
|
@@ -44,12 +43,11 @@ export type RewardManifestPageStore = {
|
|
|
44
43
|
readProofs(offset: number, count: number): Promise<readonly RewardProof[]>;
|
|
45
44
|
writeProofs(offset: number, proofs: readonly RewardProof[]): Promise<void>;
|
|
46
45
|
};
|
|
47
|
-
/**
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
export type RewardLeafDomain = typeof MIGRATOR_REWARD_LEAF_DOMAIN | typeof PRESALE_REWARD_LEAF_DOMAIN;
|
|
46
|
+
/**
|
|
47
|
+
* `blast_vault::constants::reward_leaf_domain`: every vault's rounds hash
|
|
48
|
+
* their leaves as `merkle::leaf(REWARD_LEAF_DOMAIN, bcs(leaf))`.
|
|
49
|
+
*/
|
|
50
|
+
export declare const REWARD_LEAF_DOMAIN = "blast-holder-rewards-v2";
|
|
53
51
|
/** Exact atomic-unit allocations, rounded down. Dust stays in the vault rewards balance. */
|
|
54
52
|
export declare function allocateHolderRewards(holders: readonly HolderWeight[], memeBudget: bigint, quoteBudget: bigint): {
|
|
55
53
|
allocations: RewardAllocation[];
|
|
@@ -57,13 +55,15 @@ export declare function allocateHolderRewards(holders: readonly HolderWeight[],
|
|
|
57
55
|
quoteDust: bigint;
|
|
58
56
|
};
|
|
59
57
|
/**
|
|
60
|
-
*
|
|
61
|
-
* Remainders stay holder-owned; sum quoteAllocated over every page
|
|
62
|
-
* Inputs are distinct qualifying wallets in canonical order; carry
|
|
58
|
+
* Atoms of each asset = floor(budget * wallet weight / frozen global weight), never a page
|
|
59
|
+
* denominator. Remainders stay holder-owned; sum memeAllocated and quoteAllocated over every page
|
|
60
|
+
* to calculate global dust. Inputs are distinct qualifying wallets in canonical order; carry
|
|
61
|
+
* lastAddress into the next page.
|
|
63
62
|
*/
|
|
64
|
-
export declare function allocateHolderRewardPage(holders: readonly HolderWeight[], quoteBudget: bigint, totalWeight: bigint, afterAddress?: string): {
|
|
63
|
+
export declare function allocateHolderRewardPage(holders: readonly HolderWeight[], memeBudget: bigint, quoteBudget: bigint, totalWeight: bigint, afterAddress?: string): {
|
|
65
64
|
allocations: RewardAllocation[];
|
|
66
65
|
pageWeight: bigint;
|
|
66
|
+
memeAllocated: bigint;
|
|
67
67
|
quoteAllocated: bigint;
|
|
68
68
|
lastAddress: string | undefined;
|
|
69
69
|
};
|
|
@@ -74,7 +74,6 @@ export declare function buildRewardManifest(options: {
|
|
|
74
74
|
startCheckpoint: bigint;
|
|
75
75
|
endCheckpoint: bigint;
|
|
76
76
|
allocations: readonly RewardAllocation[];
|
|
77
|
-
leafDomain: RewardLeafDomain;
|
|
78
77
|
}): RewardManifest;
|
|
79
78
|
/**
|
|
80
79
|
* Constructs the same BCS commitment/tree as buildRewardManifest using bounded
|
|
@@ -86,13 +85,13 @@ export declare function buildRewardManifestPages(options: Omit<Parameters<typeof
|
|
|
86
85
|
pageSize: number;
|
|
87
86
|
}, store: RewardManifestPageStore): Promise<RewardManifestSummary>;
|
|
88
87
|
/** Matches the contract's leaf domain and exact positional proof depth. */
|
|
89
|
-
export declare function verifyRewardProof(manifest: RewardManifest, allocation: RewardProof
|
|
88
|
+
export declare function verifyRewardProof(manifest: RewardManifest, allocation: RewardProof): boolean;
|
|
90
89
|
/** Checks one durable proof without loading every allocation; no historical or financial policy is inferred. */
|
|
91
|
-
export declare function verifyRewardSummaryProof(manifest: RewardManifestSummary, allocation: RewardProof
|
|
90
|
+
export declare function verifyRewardSummaryProof(manifest: RewardManifestSummary, allocation: RewardProof): boolean;
|
|
92
91
|
/** Structural validation only; ready-plan evidence must prove durable construction upstream. */
|
|
93
|
-
export declare function validateRewardManifestSummary(summary: RewardManifestSummary
|
|
92
|
+
export declare function validateRewardManifestSummary(summary: RewardManifestSummary): RewardManifestSummary;
|
|
94
93
|
/** Rejects edited totals, roots, ordering, proofs and manifests before creating transactions. */
|
|
95
|
-
export declare function validateRewardManifest(manifest: RewardManifest
|
|
94
|
+
export declare function validateRewardManifest(manifest: RewardManifest): RewardManifest;
|
|
96
95
|
export declare function rewardAddress(value: string): string;
|
|
97
96
|
export declare function rewardDigest(value: string): Uint8Array;
|
|
98
97
|
//# sourceMappingURL=allocations.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"allocations.d.ts","sourceRoot":"","sources":["../../src/rewards/allocations.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"allocations.d.ts","sourceRoot":"","sources":["../../src/rewards/allocations.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import { bcs } from "@mysten/sui/bcs";
|
|
|
2
2
|
import { fromHex, isValidSuiAddress, normalizeSuiAddress, toHex, } from "@mysten/sui/utils";
|
|
3
3
|
import { blake2b } from "@noble/hashes/blake2.js";
|
|
4
4
|
import { requireU64 } from "../integers.js";
|
|
5
|
-
import { blake2b256, merkleLayers, merkleNode, merkleProof, merkleRoot, } from "../merkle.js";
|
|
5
|
+
import { blake2b256, merkleLayers, merkleLeaf, merkleNode, merkleProof, merkleRoot, } from "../merkle.js";
|
|
6
6
|
export const MAX_REWARD_LEAVES = 65_536;
|
|
7
7
|
const leafBcs = bcs.struct("RewardLeaf", {
|
|
8
8
|
vault: bcs.Address,
|
|
@@ -25,10 +25,15 @@ const manifestHeaderBcs = bcs.struct("RewardManifestHeader", {
|
|
|
25
25
|
start: bcs.u64(),
|
|
26
26
|
end: bcs.u64(),
|
|
27
27
|
});
|
|
28
|
-
/**
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
/**
|
|
29
|
+
* `blast_vault::constants::reward_leaf_domain`: every vault's rounds hash
|
|
30
|
+
* their leaves as `merkle::leaf(REWARD_LEAF_DOMAIN, bcs(leaf))`.
|
|
31
|
+
*/
|
|
32
|
+
export const REWARD_LEAF_DOMAIN = "blast-holder-rewards-v2";
|
|
33
|
+
/** One leaf digest: `blake2b256(0x00 || REWARD_LEAF_DOMAIN || bcs(leaf))`. */
|
|
34
|
+
function rewardLeaf(bytes) {
|
|
35
|
+
return merkleLeaf(REWARD_LEAF_DOMAIN, bytes);
|
|
36
|
+
}
|
|
32
37
|
/** Exact atomic-unit allocations, rounded down. Dust stays in the vault rewards balance. */
|
|
33
38
|
export function allocateHolderRewards(holders, memeBudget, quoteBudget) {
|
|
34
39
|
requireU64("memeBudget", memeBudget);
|
|
@@ -58,16 +63,19 @@ export function allocateHolderRewards(holders, memeBudget, quoteBudget) {
|
|
|
58
63
|
return { allocations, memeDust, quoteDust };
|
|
59
64
|
}
|
|
60
65
|
/**
|
|
61
|
-
*
|
|
62
|
-
* Remainders stay holder-owned; sum quoteAllocated over every page
|
|
63
|
-
* Inputs are distinct qualifying wallets in canonical order; carry
|
|
66
|
+
* Atoms of each asset = floor(budget * wallet weight / frozen global weight), never a page
|
|
67
|
+
* denominator. Remainders stay holder-owned; sum memeAllocated and quoteAllocated over every page
|
|
68
|
+
* to calculate global dust. Inputs are distinct qualifying wallets in canonical order; carry
|
|
69
|
+
* lastAddress into the next page.
|
|
64
70
|
*/
|
|
65
|
-
export function allocateHolderRewardPage(holders, quoteBudget, totalWeight, afterAddress) {
|
|
71
|
+
export function allocateHolderRewardPage(holders, memeBudget, quoteBudget, totalWeight, afterAddress) {
|
|
72
|
+
requireU64("memeBudget", memeBudget);
|
|
66
73
|
requireU64("quoteBudget", quoteBudget);
|
|
67
74
|
if (totalWeight <= 0n)
|
|
68
75
|
throw new RangeError("global weight must be positive");
|
|
69
76
|
let lastAddress = afterAddress === undefined ? undefined : rewardAddress(afterAddress);
|
|
70
77
|
let pageWeight = 0n;
|
|
78
|
+
let memeAllocated = 0n;
|
|
71
79
|
let quoteAllocated = 0n;
|
|
72
80
|
const allocations = [];
|
|
73
81
|
for (const holder of holders) {
|
|
@@ -79,17 +87,24 @@ export function allocateHolderRewardPage(holders, quoteBudget, totalWeight, afte
|
|
|
79
87
|
pageWeight += holder.weight;
|
|
80
88
|
if (pageWeight > totalWeight)
|
|
81
89
|
throw new RangeError("page weight exceeds global weight");
|
|
90
|
+
const memeAmount = (memeBudget * holder.weight) / totalWeight;
|
|
82
91
|
const quoteAmount = (quoteBudget * holder.weight) / totalWeight;
|
|
83
|
-
if (quoteAmount > 0n)
|
|
84
|
-
allocations.push({ beneficiary, memeAmount
|
|
92
|
+
if (memeAmount > 0n || quoteAmount > 0n)
|
|
93
|
+
allocations.push({ beneficiary, memeAmount, quoteAmount });
|
|
94
|
+
memeAllocated += memeAmount;
|
|
85
95
|
quoteAllocated += quoteAmount;
|
|
86
96
|
lastAddress = beneficiary;
|
|
87
97
|
}
|
|
88
|
-
return {
|
|
98
|
+
return {
|
|
99
|
+
allocations,
|
|
100
|
+
pageWeight,
|
|
101
|
+
memeAllocated,
|
|
102
|
+
quoteAllocated,
|
|
103
|
+
lastAddress,
|
|
104
|
+
};
|
|
89
105
|
}
|
|
90
106
|
/** Builds the public payout list and every positional proof, independent of the signing key. */
|
|
91
107
|
export function buildRewardManifest(options) {
|
|
92
|
-
const leafPrefix = new TextEncoder().encode(options.leafDomain);
|
|
93
108
|
const vaultId = rewardAddress(options.vaultId);
|
|
94
109
|
requireU64("number", options.number);
|
|
95
110
|
requireU64("startCheckpoint", options.startCheckpoint);
|
|
@@ -125,11 +140,11 @@ export function buildRewardManifest(options) {
|
|
|
125
140
|
meme: allocation.memeAmount,
|
|
126
141
|
quote: allocation.quoteAmount,
|
|
127
142
|
}));
|
|
128
|
-
const layers = merkleLayers(leaves.map((leaf) =>
|
|
143
|
+
const layers = merkleLayers(leaves.map((leaf) => rewardLeaf(leafBcs.serialize(leaf).toBytes())));
|
|
129
144
|
const memeAmount = requireU64("total Meme", allocations.reduce((sum, item) => sum + item.memeAmount, 0n));
|
|
130
145
|
const quoteAmount = requireU64("total Quote", allocations.reduce((sum, item) => sum + item.quoteAmount, 0n));
|
|
131
146
|
return {
|
|
132
|
-
version:
|
|
147
|
+
version: 2,
|
|
133
148
|
vaultId,
|
|
134
149
|
number: options.number.toString(),
|
|
135
150
|
startCheckpoint: options.startCheckpoint.toString(),
|
|
@@ -175,7 +190,6 @@ export async function buildRewardManifestPages(options, store) {
|
|
|
175
190
|
options.pageSize < 1 ||
|
|
176
191
|
options.pageSize > MAX_REWARD_LEAVES)
|
|
177
192
|
throw new RangeError("invalid page size");
|
|
178
|
-
const leafPrefix = new TextEncoder().encode(options.leafDomain);
|
|
179
193
|
const digest = blake2b.create({ dkLen: 32 });
|
|
180
194
|
digest.update(manifestHeaderBcs
|
|
181
195
|
.serialize({
|
|
@@ -200,13 +214,13 @@ export async function buildRewardManifestPages(options, store) {
|
|
|
200
214
|
if (stored.some((hash, i) => hash !== hashes[i]))
|
|
201
215
|
throw new Error("Merkle page readback mismatch");
|
|
202
216
|
};
|
|
203
|
-
const { memeAmount, quoteAmount } = await writeManifestLeaves(options, vaultId, digest,
|
|
217
|
+
const { memeAmount, quoteAmount } = await writeManifestLeaves(options, vaultId, digest, store, writeHashes);
|
|
204
218
|
const level = await buildManifestMerkleLayers(options, readHashes, writeHashes);
|
|
205
219
|
const root = (await readHashes(level, 0, 1))[0];
|
|
206
220
|
if (root === undefined)
|
|
207
221
|
throw new Error("missing Merkle root");
|
|
208
222
|
const summary = {
|
|
209
|
-
version:
|
|
223
|
+
version: 2,
|
|
210
224
|
vaultId,
|
|
211
225
|
number: options.number.toString(),
|
|
212
226
|
startCheckpoint: options.startCheckpoint.toString(),
|
|
@@ -216,9 +230,8 @@ export async function buildRewardManifestPages(options, store) {
|
|
|
216
230
|
memeAmount: memeAmount.toString(),
|
|
217
231
|
quoteAmount: quoteAmount.toString(),
|
|
218
232
|
leafCount: options.leafCount,
|
|
219
|
-
leafDomain: options.leafDomain,
|
|
220
233
|
};
|
|
221
|
-
await writeManifestProofs(options, summary,
|
|
234
|
+
await writeManifestProofs(options, summary, store, readHashes);
|
|
222
235
|
return summary;
|
|
223
236
|
}
|
|
224
237
|
function rewardLeafBytes(options, vaultId, allocation, index) {
|
|
@@ -240,7 +253,7 @@ function rewardLeafBytes(options, vaultId, allocation, index) {
|
|
|
240
253
|
})
|
|
241
254
|
.toBytes();
|
|
242
255
|
}
|
|
243
|
-
async function writeManifestLeaves(options, vaultId, digest,
|
|
256
|
+
async function writeManifestLeaves(options, vaultId, digest, store, writeHashes) {
|
|
244
257
|
let memeAmount = 0n;
|
|
245
258
|
let quoteAmount = 0n;
|
|
246
259
|
let previous;
|
|
@@ -258,7 +271,7 @@ async function writeManifestLeaves(options, vaultId, digest, leafPrefix, store,
|
|
|
258
271
|
memeAmount = requireU64("total Meme", memeAmount + allocation.memeAmount);
|
|
259
272
|
quoteAmount = requireU64("total Quote", quoteAmount + allocation.quoteAmount);
|
|
260
273
|
digest.update(bytes);
|
|
261
|
-
hashes.push(toHex(
|
|
274
|
+
hashes.push(toHex(rewardLeaf(bytes)));
|
|
262
275
|
}
|
|
263
276
|
await writeHashes(0, offset, hashes);
|
|
264
277
|
}
|
|
@@ -285,7 +298,7 @@ async function buildManifestMerkleLayers(options, readHashes, writeHashes) {
|
|
|
285
298
|
}
|
|
286
299
|
return level;
|
|
287
300
|
}
|
|
288
|
-
async function writeManifestProofs(options, summary,
|
|
301
|
+
async function writeManifestProofs(options, summary, store, readHashes) {
|
|
289
302
|
for (let offset = 0; offset < options.leafCount; offset += options.pageSize) {
|
|
290
303
|
const count = Math.min(options.pageSize, options.leafCount - offset);
|
|
291
304
|
const allocations = await store.readAllocations(offset, count);
|
|
@@ -293,7 +306,7 @@ async function writeManifestProofs(options, summary, leafPrefix, store, readHash
|
|
|
293
306
|
throw new Error("incomplete allocation page");
|
|
294
307
|
const hashes = await readHashes(0, offset, count);
|
|
295
308
|
const proofs = allocations.map((allocation, i) => {
|
|
296
|
-
if (toHex(
|
|
309
|
+
if (toHex(rewardLeaf(rewardLeafBytes(options, summary.vaultId, allocation, offset + i))) !== hashes[i])
|
|
297
310
|
throw new Error("allocation snapshot changed during construction");
|
|
298
311
|
return {
|
|
299
312
|
index: (offset + i).toString(),
|
|
@@ -305,7 +318,7 @@ async function writeManifestProofs(options, summary, leafPrefix, store, readHash
|
|
|
305
318
|
});
|
|
306
319
|
await fillManifestProofs(options, offset, proofs, readHashes);
|
|
307
320
|
for (const proof of proofs)
|
|
308
|
-
if (!verifyRewardSummaryProof(summary, proof
|
|
321
|
+
if (!verifyRewardSummaryProof(summary, proof))
|
|
309
322
|
throw new Error("proof does not match constructed root");
|
|
310
323
|
await store.writeProofs(offset, proofs);
|
|
311
324
|
const stored = await store.readProofs(offset, count);
|
|
@@ -346,14 +359,11 @@ function rewardProofPagesMatch(stored, proofs) {
|
|
|
346
359
|
}));
|
|
347
360
|
}
|
|
348
361
|
/** Matches the contract's leaf domain and exact positional proof depth. */
|
|
349
|
-
export function verifyRewardProof(manifest, allocation
|
|
350
|
-
return verifyRewardSummaryProof({ ...manifest, leafCount: manifest.allocations.length
|
|
362
|
+
export function verifyRewardProof(manifest, allocation) {
|
|
363
|
+
return verifyRewardSummaryProof({ ...manifest, leafCount: manifest.allocations.length }, allocation);
|
|
351
364
|
}
|
|
352
365
|
/** Checks one durable proof without loading every allocation; no historical or financial policy is inferred. */
|
|
353
|
-
export function verifyRewardSummaryProof(manifest, allocation
|
|
354
|
-
if (manifest.leafDomain !== leafDomain)
|
|
355
|
-
return false;
|
|
356
|
-
const leafPrefix = new TextEncoder().encode(leafDomain);
|
|
366
|
+
export function verifyRewardSummaryProof(manifest, allocation) {
|
|
357
367
|
try {
|
|
358
368
|
let index = Number(requireU64("index", BigInt(allocation.index)));
|
|
359
369
|
const count = manifest.leafCount;
|
|
@@ -363,7 +373,7 @@ export function verifyRewardSummaryProof(manifest, allocation, leafDomain) {
|
|
|
363
373
|
index >= count ||
|
|
364
374
|
allocation.proof.length !== Math.ceil(Math.log2(count)))
|
|
365
375
|
return false;
|
|
366
|
-
let digest =
|
|
376
|
+
let digest = rewardLeaf(leafBcs
|
|
367
377
|
.serialize({
|
|
368
378
|
vault: rewardAddress(manifest.vaultId),
|
|
369
379
|
number: requireU64("number", BigInt(manifest.number)),
|
|
@@ -372,7 +382,7 @@ export function verifyRewardSummaryProof(manifest, allocation, leafDomain) {
|
|
|
372
382
|
meme: requireU64("meme", BigInt(allocation.memeAmount)),
|
|
373
383
|
quote: requireU64("quote", BigInt(allocation.quoteAmount)),
|
|
374
384
|
})
|
|
375
|
-
.toBytes())
|
|
385
|
+
.toBytes());
|
|
376
386
|
for (const sibling of allocation.proof) {
|
|
377
387
|
const bytes = rewardDigest(sibling);
|
|
378
388
|
digest =
|
|
@@ -386,10 +396,8 @@ export function verifyRewardSummaryProof(manifest, allocation, leafDomain) {
|
|
|
386
396
|
}
|
|
387
397
|
}
|
|
388
398
|
/** Structural validation only; ready-plan evidence must prove durable construction upstream. */
|
|
389
|
-
export function validateRewardManifestSummary(summary
|
|
390
|
-
if (summary.
|
|
391
|
-
throw new TypeError("manifest leaf domain mismatch");
|
|
392
|
-
if (summary.version !== 1)
|
|
399
|
+
export function validateRewardManifestSummary(summary) {
|
|
400
|
+
if (summary.version !== 2)
|
|
393
401
|
throw new Error("unsupported manifest version");
|
|
394
402
|
if (summary.vaultId !== rewardAddress(summary.vaultId))
|
|
395
403
|
throw new TypeError("noncanonical vault");
|
|
@@ -417,8 +425,8 @@ export function validateRewardManifestSummary(summary, leafDomain) {
|
|
|
417
425
|
return summary;
|
|
418
426
|
}
|
|
419
427
|
/** Rejects edited totals, roots, ordering, proofs and manifests before creating transactions. */
|
|
420
|
-
export function validateRewardManifest(manifest
|
|
421
|
-
if (manifest.version !==
|
|
428
|
+
export function validateRewardManifest(manifest) {
|
|
429
|
+
if (manifest.version !== 2)
|
|
422
430
|
throw new Error("unsupported manifest version");
|
|
423
431
|
const expected = buildRewardManifest({
|
|
424
432
|
vaultId: manifest.vaultId,
|
|
@@ -430,7 +438,6 @@ export function validateRewardManifest(manifest, leafDomain) {
|
|
|
430
438
|
memeAmount: BigInt(allocation.memeAmount),
|
|
431
439
|
quoteAmount: BigInt(allocation.quoteAmount),
|
|
432
440
|
})),
|
|
433
|
-
leafDomain,
|
|
434
441
|
});
|
|
435
442
|
for (const key of [
|
|
436
443
|
"vaultId",
|
|
@@ -469,7 +476,4 @@ export function rewardDigest(value) {
|
|
|
469
476
|
throw new TypeError("digest must be 32 canonical hex bytes");
|
|
470
477
|
return fromHex(value);
|
|
471
478
|
}
|
|
472
|
-
function concat(left, right) {
|
|
473
|
-
return new Uint8Array([...left, ...right]);
|
|
474
|
-
}
|
|
475
479
|
//# sourceMappingURL=allocations.js.map
|