@boostxyz/sdk 0.0.0-alpha.2 → 0.0.0-alpha.20
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/Actions/Action.cjs +2 -1
- package/dist/Actions/Action.cjs.map +1 -0
- package/dist/Actions/Action.d.ts +1 -1
- package/dist/Actions/Action.d.ts.map +1 -1
- package/dist/Actions/Action.js +14 -12
- package/dist/Actions/Action.js.map +1 -0
- package/dist/Actions/ContractAction.d.ts +57 -14
- package/dist/Actions/ContractAction.d.ts.map +1 -1
- package/dist/Actions/ERC721MintAction.d.ts +50 -23
- package/dist/Actions/ERC721MintAction.d.ts.map +1 -1
- package/dist/Actions/EventAction.cjs +2 -1
- package/dist/Actions/EventAction.cjs.map +1 -0
- package/dist/Actions/EventAction.d.ts +405 -36
- package/dist/Actions/EventAction.d.ts.map +1 -1
- package/dist/Actions/EventAction.js +15 -209
- package/dist/Actions/EventAction.js.map +1 -0
- package/dist/AllowLists/AllowList.cjs +2 -1
- package/dist/AllowLists/AllowList.cjs.map +1 -0
- package/dist/AllowLists/AllowList.d.ts +6 -5
- package/dist/AllowLists/AllowList.d.ts.map +1 -1
- package/dist/AllowLists/AllowList.js +46 -22
- package/dist/AllowLists/AllowList.js.map +1 -0
- package/dist/AllowLists/OpenAllowList.d.ts +423 -0
- package/dist/AllowLists/OpenAllowList.d.ts.map +1 -0
- package/dist/AllowLists/SimpleAllowList.cjs +2 -1
- package/dist/AllowLists/SimpleAllowList.cjs.map +1 -0
- package/dist/AllowLists/SimpleAllowList.d.ts +124 -40
- package/dist/AllowLists/SimpleAllowList.d.ts.map +1 -1
- package/dist/AllowLists/SimpleAllowList.js +77 -77
- package/dist/AllowLists/SimpleAllowList.js.map +1 -0
- package/dist/AllowLists/SimpleDenyList.cjs +2 -1
- package/dist/AllowLists/SimpleDenyList.cjs.map +1 -0
- package/dist/AllowLists/SimpleDenyList.d.ts +234 -13
- package/dist/AllowLists/SimpleDenyList.d.ts.map +1 -1
- package/dist/AllowLists/SimpleDenyList.js +12 -200
- package/dist/AllowLists/SimpleDenyList.js.map +1 -0
- package/dist/Auth/Auth.cjs +1 -0
- package/dist/Auth/Auth.cjs.map +1 -0
- package/dist/Auth/Auth.js +1 -0
- package/dist/Auth/Auth.js.map +1 -0
- package/dist/Auth/PassthroughAuth.cjs +2 -1
- package/dist/Auth/PassthroughAuth.cjs.map +1 -0
- package/dist/Auth/PassthroughAuth.js +5 -4
- package/dist/Auth/PassthroughAuth.js.map +1 -0
- package/dist/Boost.cjs +2 -1
- package/dist/Boost.cjs.map +1 -0
- package/dist/Boost.d.ts +111 -1
- package/dist/Boost.d.ts.map +1 -1
- package/dist/Boost.js +140 -5
- package/dist/Boost.js.map +1 -0
- package/dist/BoostCore-3-U1xTQN.cjs +3 -0
- package/dist/BoostCore-3-U1xTQN.cjs.map +1 -0
- package/dist/BoostCore-DVGBUr2y.js +1477 -0
- package/dist/BoostCore-DVGBUr2y.js.map +1 -0
- package/dist/BoostCore.cjs +2 -2
- package/dist/BoostCore.cjs.map +1 -0
- package/dist/BoostCore.d.ts +166 -43
- package/dist/BoostCore.d.ts.map +1 -1
- package/dist/BoostCore.js +30 -1103
- package/dist/BoostCore.js.map +1 -0
- package/dist/BoostRegistry.cjs +2 -1
- package/dist/BoostRegistry.cjs.map +1 -0
- package/dist/BoostRegistry.d.ts +64 -23
- package/dist/BoostRegistry.d.ts.map +1 -1
- package/dist/BoostRegistry.js +162 -88
- package/dist/BoostRegistry.js.map +1 -0
- package/dist/Budgets/Budget.cjs +2 -1
- package/dist/Budgets/Budget.cjs.map +1 -0
- package/dist/Budgets/Budget.d.ts +1 -1
- package/dist/Budgets/Budget.d.ts.map +1 -1
- package/dist/Budgets/Budget.js +15 -13
- package/dist/Budgets/Budget.js.map +1 -0
- package/dist/Budgets/ManagedBudget.cjs +2 -1
- package/dist/Budgets/ManagedBudget.cjs.map +1 -0
- package/dist/Budgets/ManagedBudget.d.ts +78 -188
- package/dist/Budgets/ManagedBudget.d.ts.map +1 -1
- package/dist/Budgets/ManagedBudget.js +86 -286
- package/dist/Budgets/ManagedBudget.js.map +1 -0
- package/dist/Budgets/VestingBudget.d.ts +243 -87
- package/dist/Budgets/VestingBudget.d.ts.map +1 -1
- package/dist/Deployable/Contract.cjs +2 -1
- package/dist/Deployable/Contract.cjs.map +1 -0
- package/dist/Deployable/Contract.d.ts +4 -5
- package/dist/Deployable/Contract.d.ts.map +1 -1
- package/dist/Deployable/Contract.js +7 -8
- package/dist/Deployable/Contract.js.map +1 -0
- package/dist/Deployable/Deployable.cjs +1 -0
- package/dist/Deployable/Deployable.cjs.map +1 -0
- package/dist/Deployable/Deployable.d.ts +9 -3
- package/dist/Deployable/Deployable.d.ts.map +1 -1
- package/dist/Deployable/Deployable.js +10 -5
- package/dist/Deployable/Deployable.js.map +1 -0
- package/dist/Deployable/DeployableTarget.cjs +2 -1
- package/dist/Deployable/DeployableTarget.cjs.map +1 -0
- package/dist/Deployable/DeployableTarget.d.ts +16 -15
- package/dist/Deployable/DeployableTarget.d.ts.map +1 -1
- package/dist/Deployable/DeployableTarget.js +49 -42
- package/dist/Deployable/DeployableTarget.js.map +1 -0
- package/dist/Deployable/DeployableTargetWithRBAC.cjs +2 -0
- package/dist/Deployable/DeployableTargetWithRBAC.cjs.map +1 -0
- package/dist/Deployable/DeployableTargetWithRBAC.d.ts +179 -0
- package/dist/Deployable/DeployableTargetWithRBAC.d.ts.map +1 -0
- package/dist/Deployable/DeployableTargetWithRBAC.js +222 -0
- package/dist/Deployable/DeployableTargetWithRBAC.js.map +1 -0
- package/dist/EventAction-CIPqmAoP.js +1450 -0
- package/dist/EventAction-CIPqmAoP.js.map +1 -0
- package/dist/EventAction-d-oeqZQs.cjs +2 -0
- package/dist/EventAction-d-oeqZQs.cjs.map +1 -0
- package/dist/Incentive-Bp8Sez7M.js +298 -0
- package/dist/Incentive-Bp8Sez7M.js.map +1 -0
- package/dist/Incentive-Djnzseoj.cjs +2 -0
- package/dist/Incentive-Djnzseoj.cjs.map +1 -0
- package/dist/Incentives/AllowListIncentive.cjs +2 -1
- package/dist/Incentives/AllowListIncentive.cjs.map +1 -0
- package/dist/Incentives/AllowListIncentive.d.ts +49 -19
- package/dist/Incentives/AllowListIncentive.d.ts.map +1 -1
- package/dist/Incentives/AllowListIncentive.js +50 -34
- package/dist/Incentives/AllowListIncentive.js.map +1 -0
- package/dist/Incentives/CGDAIncentive.cjs +2 -1
- package/dist/Incentives/CGDAIncentive.cjs.map +1 -0
- package/dist/Incentives/CGDAIncentive.d.ts +118 -22
- package/dist/Incentives/CGDAIncentive.d.ts.map +1 -1
- package/dist/Incentives/CGDAIncentive.js +67 -42
- package/dist/Incentives/CGDAIncentive.js.map +1 -0
- package/dist/Incentives/ERC1155Incentive.d.ts +99 -38
- package/dist/Incentives/ERC1155Incentive.d.ts.map +1 -1
- package/dist/Incentives/ERC20Incentive.cjs +2 -1
- package/dist/Incentives/ERC20Incentive.cjs.map +1 -0
- package/dist/Incentives/ERC20Incentive.d.ts +73 -29
- package/dist/Incentives/ERC20Incentive.d.ts.map +1 -1
- package/dist/Incentives/ERC20Incentive.js +71 -48
- package/dist/Incentives/ERC20Incentive.js.map +1 -0
- package/dist/Incentives/ERC20VariableCriteriaIncentive.d.ts +523 -0
- package/dist/Incentives/ERC20VariableCriteriaIncentive.d.ts.map +1 -0
- package/dist/Incentives/ERC20VariableIncentive.d.ts +65 -28
- package/dist/Incentives/ERC20VariableIncentive.d.ts.map +1 -1
- package/dist/Incentives/Incentive.cjs +2 -1
- package/dist/Incentives/Incentive.cjs.map +1 -0
- package/dist/Incentives/Incentive.d.ts +4 -7
- package/dist/Incentives/Incentive.d.ts.map +1 -1
- package/dist/Incentives/Incentive.js +17 -278
- package/dist/Incentives/Incentive.js.map +1 -0
- package/dist/Incentives/PointsIncentive.cjs +2 -1
- package/dist/Incentives/PointsIncentive.cjs.map +1 -0
- package/dist/Incentives/PointsIncentive.d.ts +65 -21
- package/dist/Incentives/PointsIncentive.d.ts.map +1 -1
- package/dist/Incentives/PointsIncentive.js +57 -36
- package/dist/Incentives/PointsIncentive.js.map +1 -0
- package/dist/SimpleDenyList-BwfNjRsg.cjs +2 -0
- package/dist/SimpleDenyList-BwfNjRsg.cjs.map +1 -0
- package/dist/SimpleDenyList-Cn5WpNn0.js +132 -0
- package/dist/SimpleDenyList-Cn5WpNn0.js.map +1 -0
- package/dist/Validators/SignerValidator.cjs +2 -1
- package/dist/Validators/SignerValidator.cjs.map +1 -0
- package/dist/Validators/SignerValidator.d.ts +310 -17
- package/dist/Validators/SignerValidator.d.ts.map +1 -1
- package/dist/Validators/SignerValidator.js +165 -36
- package/dist/Validators/SignerValidator.js.map +1 -0
- package/dist/Validators/Validator.cjs +2 -1
- package/dist/Validators/Validator.cjs.map +1 -0
- package/dist/Validators/Validator.d.ts +2 -2
- package/dist/Validators/Validator.d.ts.map +1 -1
- package/dist/Validators/Validator.js +12 -10
- package/dist/Validators/Validator.js.map +1 -0
- package/dist/claiming.cjs +2 -0
- package/dist/claiming.cjs.map +1 -0
- package/dist/claiming.d.ts +43 -0
- package/dist/claiming.d.ts.map +1 -0
- package/dist/claiming.js +17 -0
- package/dist/claiming.js.map +1 -0
- package/dist/componentInterfaces-D09mhzxO.cjs +2 -0
- package/dist/componentInterfaces-D09mhzxO.cjs.map +1 -0
- package/dist/componentInterfaces-RXBMI5yH.js +14 -0
- package/dist/componentInterfaces-RXBMI5yH.js.map +1 -0
- package/dist/deployments-BM42vImE.js +43 -0
- package/dist/deployments-BM42vImE.js.map +1 -0
- package/dist/deployments-CMdF5uEC.cjs +2 -0
- package/dist/deployments-CMdF5uEC.cjs.map +1 -0
- package/dist/deployments.json +41 -0
- package/dist/errors.cjs +2 -1
- package/dist/errors.cjs.map +1 -0
- package/dist/errors.d.ts +403 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +285 -39
- package/dist/errors.js.map +1 -0
- package/dist/generated-B0tk-c9b.cjs +3 -0
- package/dist/generated-B0tk-c9b.cjs.map +1 -0
- package/dist/{generated-x_abr3Yv.js → generated-B7VaSah4.js} +2058 -2541
- package/dist/generated-B7VaSah4.js.map +1 -0
- package/dist/index.cjs +2 -1
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +10 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +143 -1353
- package/dist/index.js.map +1 -0
- package/dist/transfers.cjs +2 -0
- package/dist/transfers.cjs.map +1 -0
- package/dist/transfers.d.ts +198 -0
- package/dist/transfers.d.ts.map +1 -0
- package/dist/transfers.js +84 -0
- package/dist/transfers.js.map +1 -0
- package/dist/utils.cjs +2 -1
- package/dist/utils.cjs.map +1 -0
- package/dist/utils.d.ts +26 -1350
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +38 -636
- package/dist/utils.js.map +1 -0
- package/package.json +37 -11
- package/src/Actions/Action.test.ts +79 -0
- package/src/Actions/Action.ts +61 -0
- package/src/Actions/ContractAction.test.ts +197 -0
- package/src/Actions/ContractAction.ts +300 -0
- package/src/Actions/ERC721MintAction.test.ts +112 -0
- package/src/Actions/ERC721MintAction.ts +291 -0
- package/src/Actions/EventAction.test.ts +787 -0
- package/src/Actions/EventAction.ts +1214 -0
- package/src/AllowLists/AllowList.test.ts +64 -0
- package/src/AllowLists/AllowList.ts +62 -0
- package/src/AllowLists/OpenAllowList.test.ts +40 -0
- package/src/AllowLists/OpenAllowList.ts +45 -0
- package/src/AllowLists/SimpleAllowList.test.ts +52 -0
- package/src/AllowLists/SimpleAllowList.ts +262 -0
- package/src/AllowLists/SimpleDenyList.test.ts +52 -0
- package/src/AllowLists/SimpleDenyList.ts +250 -0
- package/src/Auth/Auth.ts +11 -0
- package/src/Auth/PassthroughAuth.test.ts +12 -0
- package/src/Auth/PassthroughAuth.ts +80 -0
- package/src/Boost.ts +309 -0
- package/src/BoostCore.test.ts +827 -0
- package/src/BoostCore.ts +1447 -0
- package/src/BoostRegistry.ts +543 -0
- package/src/Budgets/Budget.test.ts +27 -0
- package/src/Budgets/Budget.ts +60 -0
- package/src/Budgets/ManagedBudget.test.ts +217 -0
- package/src/Budgets/ManagedBudget.ts +534 -0
- package/src/Budgets/VestingBudget.test.ts +123 -0
- package/src/Budgets/VestingBudget.ts +530 -0
- package/src/Deployable/Contract.ts +228 -0
- package/src/Deployable/Deployable.ts +250 -0
- package/src/Deployable/DeployableTarget.ts +234 -0
- package/src/Deployable/DeployableTargetWithRBAC.ts +323 -0
- package/src/Incentives/AllowListIncentive.test.ts +143 -0
- package/src/Incentives/AllowListIncentive.ts +336 -0
- package/src/Incentives/CGDAIncentive.test.ts +132 -0
- package/src/Incentives/CGDAIncentive.ts +470 -0
- package/src/Incentives/ERC1155Incentive.test.ts +87 -0
- package/src/Incentives/ERC1155Incentive.ts +465 -0
- package/src/Incentives/ERC20Incentive.test.ts +130 -0
- package/src/Incentives/ERC20Incentive.ts +484 -0
- package/src/Incentives/ERC20VariableCriteriaIncentive.test.ts +184 -0
- package/src/Incentives/ERC20VariableCriteriaIncentive.ts +309 -0
- package/src/Incentives/ERC20VariableIncentive.test.ts +136 -0
- package/src/Incentives/ERC20VariableIncentive.ts +422 -0
- package/src/Incentives/Incentive.test.ts +92 -0
- package/src/Incentives/Incentive.ts +86 -0
- package/src/Incentives/PointsIncentive.test.ts +139 -0
- package/src/Incentives/PointsIncentive.ts +367 -0
- package/src/Validators/SignerValidator.test.ts +159 -0
- package/src/Validators/SignerValidator.ts +683 -0
- package/src/Validators/Validator.test.ts +21 -0
- package/src/Validators/Validator.ts +55 -0
- package/src/claiming.ts +56 -0
- package/src/errors.ts +844 -0
- package/src/index.test.ts +122 -0
- package/src/index.ts +58 -0
- package/src/transfers.ts +284 -0
- package/src/utils.test.ts +44 -0
- package/src/utils.ts +247 -0
- package/dist/Budgets/SimpleBudget.d.ts +0 -793
- package/dist/Budgets/SimpleBudget.d.ts.map +0 -1
- package/dist/generated-BaaleHW-.cjs +0 -2
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { readPointsBalanceOf, writePointsGrantRoles } from "@boostxyz/evm";
|
|
2
|
+
import { loadFixture } from "@nomicfoundation/hardhat-network-helpers";
|
|
3
|
+
import { isAddress, pad, parseEther, zeroAddress } from "viem";
|
|
4
|
+
import { beforeAll, beforeEach, describe, expect, test } from "vitest";
|
|
5
|
+
import type { MockPoints } from "@boostxyz/test/MockPoints";
|
|
6
|
+
import { accounts } from "@boostxyz/test/accounts";
|
|
7
|
+
import {
|
|
8
|
+
type Fixtures,
|
|
9
|
+
defaultOptions,
|
|
10
|
+
deployFixtures,
|
|
11
|
+
freshBoost,
|
|
12
|
+
freshPoints,
|
|
13
|
+
} from "@boostxyz/test/helpers";
|
|
14
|
+
import { bytes4 } from "../utils";
|
|
15
|
+
import { PointsIncentive } from "./PointsIncentive";
|
|
16
|
+
|
|
17
|
+
let fixtures: Fixtures, points: MockPoints;
|
|
18
|
+
|
|
19
|
+
describe("PointsIncentive", () => {
|
|
20
|
+
beforeAll(async () => {
|
|
21
|
+
fixtures = await loadFixture(deployFixtures(defaultOptions));
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
beforeEach(async () => {
|
|
25
|
+
points = await loadFixture(freshPoints);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test("can successfully be deployed", async () => {
|
|
29
|
+
const action = new PointsIncentive(defaultOptions, {
|
|
30
|
+
venue: zeroAddress,
|
|
31
|
+
selector: "0xdeadb33f",
|
|
32
|
+
reward: 1n,
|
|
33
|
+
limit: 1n,
|
|
34
|
+
});
|
|
35
|
+
await action.deploy();
|
|
36
|
+
expect(isAddress(action.assertValidAddress())).toBe(true);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test("can claim", async () => {
|
|
40
|
+
// biome-ignore lint/style/noNonNullAssertion: we know this is defined
|
|
41
|
+
const referrer = accounts.at(1)!.account!;
|
|
42
|
+
// biome-ignore lint/style/noNonNullAssertion: we know this is defined
|
|
43
|
+
const trustedSigner = accounts.at(0)!;
|
|
44
|
+
const pointsIncentive = fixtures.core.PointsIncentive({
|
|
45
|
+
venue: points.assertValidAddress(),
|
|
46
|
+
selector: bytes4("issue(address,uint256)"),
|
|
47
|
+
reward: 1n,
|
|
48
|
+
limit: 10n,
|
|
49
|
+
});
|
|
50
|
+
const boost = await freshBoost(fixtures, {
|
|
51
|
+
incentives: [pointsIncentive],
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const claimant = trustedSigner.account;
|
|
55
|
+
const incentiveData = pad("0xdef456232173821931823712381232131391321934");
|
|
56
|
+
const incentiveQuantity = 1;
|
|
57
|
+
const claimDataPayload = await boost.validator.encodeClaimData({
|
|
58
|
+
signer: trustedSigner,
|
|
59
|
+
incentiveData,
|
|
60
|
+
chainId: defaultOptions.config.chains[0].id,
|
|
61
|
+
incentiveQuantity,
|
|
62
|
+
claimant,
|
|
63
|
+
boostId: boost.id,
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
await writePointsGrantRoles(defaultOptions.config, {
|
|
67
|
+
address: points.assertValidAddress(),
|
|
68
|
+
args: [pointsIncentive.assertValidAddress(), 2n],
|
|
69
|
+
account: defaultOptions.account,
|
|
70
|
+
});
|
|
71
|
+
await fixtures.core.claimIncentive(
|
|
72
|
+
boost.id,
|
|
73
|
+
0n,
|
|
74
|
+
referrer,
|
|
75
|
+
claimDataPayload,
|
|
76
|
+
{ value: parseEther("0.000075") },
|
|
77
|
+
);
|
|
78
|
+
expect(
|
|
79
|
+
await readPointsBalanceOf(defaultOptions.config, {
|
|
80
|
+
address: points.assertValidAddress(),
|
|
81
|
+
args: [defaultOptions.account.address],
|
|
82
|
+
}),
|
|
83
|
+
).toBe(1n);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test("cannot claim twice", async () => {
|
|
87
|
+
const reward = 1n;
|
|
88
|
+
// biome-ignore lint/style/noNonNullAssertion: we know this is defined
|
|
89
|
+
const referrer = accounts.at(1)!.account!;
|
|
90
|
+
// biome-ignore lint/style/noNonNullAssertion: we know this is defined
|
|
91
|
+
const trustedSigner = accounts.at(0)!;
|
|
92
|
+
|
|
93
|
+
const pointsIncentive = fixtures.core.PointsIncentive({
|
|
94
|
+
venue: points.assertValidAddress(),
|
|
95
|
+
selector: bytes4("issue(address,uint256)"),
|
|
96
|
+
reward,
|
|
97
|
+
limit: 10n,
|
|
98
|
+
});
|
|
99
|
+
const boost = await freshBoost(fixtures, {
|
|
100
|
+
incentives: [pointsIncentive],
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
const claimant = trustedSigner.account;
|
|
104
|
+
const incentiveData = pad("0xdef456232173821931823712381232131391321934");
|
|
105
|
+
const incentiveQuantity = 1;
|
|
106
|
+
const claimDataPayload = await boost.validator.encodeClaimData({
|
|
107
|
+
signer: trustedSigner,
|
|
108
|
+
incentiveData,
|
|
109
|
+
chainId: defaultOptions.config.chains[0].id,
|
|
110
|
+
incentiveQuantity,
|
|
111
|
+
claimant,
|
|
112
|
+
boostId: boost.id,
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
await writePointsGrantRoles(defaultOptions.config, {
|
|
116
|
+
address: points.assertValidAddress(),
|
|
117
|
+
args: [pointsIncentive.assertValidAddress(), 2n],
|
|
118
|
+
account: defaultOptions.account,
|
|
119
|
+
});
|
|
120
|
+
await fixtures.core.claimIncentive(
|
|
121
|
+
boost.id,
|
|
122
|
+
0n,
|
|
123
|
+
referrer,
|
|
124
|
+
claimDataPayload,
|
|
125
|
+
{ value: parseEther("0.000075") },
|
|
126
|
+
);
|
|
127
|
+
try {
|
|
128
|
+
await fixtures.core.claimIncentive(
|
|
129
|
+
boost.id,
|
|
130
|
+
0n,
|
|
131
|
+
referrer,
|
|
132
|
+
claimDataPayload,
|
|
133
|
+
{ value: parseEther("0.000075") },
|
|
134
|
+
);
|
|
135
|
+
} catch (e) {
|
|
136
|
+
expect(e).toBeInstanceOf(Error);
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
});
|
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
import {
|
|
2
|
+
pointsIncentiveAbi,
|
|
3
|
+
readPointsIncentiveClaimed,
|
|
4
|
+
readPointsIncentiveClaims,
|
|
5
|
+
readPointsIncentiveCurrentReward,
|
|
6
|
+
readPointsIncentiveIsClaimable,
|
|
7
|
+
readPointsIncentiveLimit,
|
|
8
|
+
readPointsIncentiveReward,
|
|
9
|
+
readPointsIncentiveSelector,
|
|
10
|
+
readPointsIncentiveVenue,
|
|
11
|
+
simulatePointsIncentiveClaim,
|
|
12
|
+
writePointsIncentiveClaim,
|
|
13
|
+
} from '@boostxyz/evm';
|
|
14
|
+
import { bytecode } from '@boostxyz/evm/artifacts/contracts/incentives/PointsIncentive.sol/PointsIncentive.json';
|
|
15
|
+
import {
|
|
16
|
+
type Address,
|
|
17
|
+
type ContractEventName,
|
|
18
|
+
type Hex,
|
|
19
|
+
encodeAbiParameters,
|
|
20
|
+
} from 'viem';
|
|
21
|
+
import { PointsIncentive as PointsIncentiveBases } from '../../dist/deployments.json';
|
|
22
|
+
import type {
|
|
23
|
+
DeployableOptions,
|
|
24
|
+
GenericDeployableParams,
|
|
25
|
+
} from '../Deployable/Deployable';
|
|
26
|
+
import { DeployableTarget } from '../Deployable/DeployableTarget';
|
|
27
|
+
import { type ClaimPayload, prepareClaimPayload } from '../claiming';
|
|
28
|
+
import {
|
|
29
|
+
type GenericLog,
|
|
30
|
+
type ReadParams,
|
|
31
|
+
RegistryType,
|
|
32
|
+
type WriteParams,
|
|
33
|
+
} from '../utils';
|
|
34
|
+
|
|
35
|
+
export { pointsIncentiveAbi };
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* The object representation of a `PointsIncentive.InitPayload`
|
|
39
|
+
*
|
|
40
|
+
* @export
|
|
41
|
+
* @interface PointsIncentivePayload
|
|
42
|
+
* @typedef {PointsIncentivePayload}
|
|
43
|
+
*/
|
|
44
|
+
export interface PointsIncentivePayload {
|
|
45
|
+
/**
|
|
46
|
+
* The address of the points contract
|
|
47
|
+
*
|
|
48
|
+
* @type {Address}
|
|
49
|
+
*/
|
|
50
|
+
venue: Address;
|
|
51
|
+
/**
|
|
52
|
+
* The selector for the issuance function on the points contract
|
|
53
|
+
*
|
|
54
|
+
* @type {Hex}
|
|
55
|
+
*/
|
|
56
|
+
selector: Hex;
|
|
57
|
+
/**
|
|
58
|
+
* The reward amount issued for each claim
|
|
59
|
+
*
|
|
60
|
+
* @type {bigint}
|
|
61
|
+
*/
|
|
62
|
+
reward: bigint;
|
|
63
|
+
/**
|
|
64
|
+
* The maximum number of claims that can be made (one per address)
|
|
65
|
+
*
|
|
66
|
+
* @type {bigint}
|
|
67
|
+
*/
|
|
68
|
+
limit: bigint;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* A generic `viem.Log` event with support for `PointsIncentive` event types.
|
|
73
|
+
*
|
|
74
|
+
* @export
|
|
75
|
+
* @typedef {PointsIncentiveLog}
|
|
76
|
+
* @template {ContractEventName<
|
|
77
|
+
* typeof pointsIncentiveAbi
|
|
78
|
+
* >} [event=ContractEventName<typeof pointsIncentiveAbi>]
|
|
79
|
+
*/
|
|
80
|
+
export type PointsIncentiveLog<
|
|
81
|
+
event extends ContractEventName<
|
|
82
|
+
typeof pointsIncentiveAbi
|
|
83
|
+
> = ContractEventName<typeof pointsIncentiveAbi>,
|
|
84
|
+
> = GenericLog<typeof pointsIncentiveAbi, event>;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* A simple on-chain points incentive implementation that allows claiming of soulbound tokens.
|
|
88
|
+
*
|
|
89
|
+
* In order for any claim to be successful:
|
|
90
|
+
* - The claimer must not have already claimed the incentive; and
|
|
91
|
+
* - The maximum number of claims must not have been reached; and
|
|
92
|
+
* - This contract must be authorized to operate the points contract's issuance function
|
|
93
|
+
*
|
|
94
|
+
* @export
|
|
95
|
+
* @class PointsIncentive
|
|
96
|
+
* @typedef {PointsIncentive}
|
|
97
|
+
* @extends {DeployableTarget<PointsIncentivePayload>}
|
|
98
|
+
*/
|
|
99
|
+
export class PointsIncentive extends DeployableTarget<
|
|
100
|
+
PointsIncentivePayload,
|
|
101
|
+
typeof pointsIncentiveAbi
|
|
102
|
+
> {
|
|
103
|
+
public override readonly abi = pointsIncentiveAbi;
|
|
104
|
+
/**
|
|
105
|
+
* @inheritdoc
|
|
106
|
+
*
|
|
107
|
+
* @public
|
|
108
|
+
* @static
|
|
109
|
+
* @type {Record<number, Address>}
|
|
110
|
+
*/
|
|
111
|
+
public static override bases: Record<number, Address> = {
|
|
112
|
+
...(PointsIncentiveBases as Record<number, Address>),
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* @inheritdoc
|
|
116
|
+
*
|
|
117
|
+
* @public
|
|
118
|
+
* @static
|
|
119
|
+
* @type {RegistryType}
|
|
120
|
+
*/
|
|
121
|
+
public static override registryType: RegistryType = RegistryType.INCENTIVE;
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* The number of claims that have been made
|
|
125
|
+
*
|
|
126
|
+
* @public
|
|
127
|
+
* @async
|
|
128
|
+
* @param {?ReadParams} [params]
|
|
129
|
+
* @returns {Promise<bigint>}
|
|
130
|
+
*/
|
|
131
|
+
public async claims(
|
|
132
|
+
params?: ReadParams<typeof pointsIncentiveAbi, 'claims'>,
|
|
133
|
+
) {
|
|
134
|
+
return await readPointsIncentiveClaims(this._config, {
|
|
135
|
+
address: this.assertValidAddress(),
|
|
136
|
+
args: [],
|
|
137
|
+
// biome-ignore lint/suspicious/noExplicitAny: Accept any shape of valid wagmi/viem parameters, wagmi does the same thing internally
|
|
138
|
+
...(params as any),
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* The current reward
|
|
144
|
+
*
|
|
145
|
+
* @public
|
|
146
|
+
* @async
|
|
147
|
+
* @param {?ReadParams} [params]
|
|
148
|
+
* @returns {Promise<bigint>} - The current reward
|
|
149
|
+
*/
|
|
150
|
+
public async currentReward(
|
|
151
|
+
params?: ReadParams<typeof pointsIncentiveAbi, 'currentReward'>,
|
|
152
|
+
) {
|
|
153
|
+
return await readPointsIncentiveCurrentReward(this._config, {
|
|
154
|
+
address: this.assertValidAddress(),
|
|
155
|
+
args: [],
|
|
156
|
+
// biome-ignore lint/suspicious/noExplicitAny: Accept any shape of valid wagmi/viem parameters, wagmi does the same thing internally
|
|
157
|
+
...(params as any),
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* The reward amount issued for each claim
|
|
163
|
+
*
|
|
164
|
+
* @public
|
|
165
|
+
* @async
|
|
166
|
+
* @param {?ReadParams} [params]
|
|
167
|
+
* @returns {Promise<bigint>} The reward amount issued for each claim
|
|
168
|
+
*/
|
|
169
|
+
public async reward(
|
|
170
|
+
params?: ReadParams<typeof pointsIncentiveAbi, 'reward'>,
|
|
171
|
+
) {
|
|
172
|
+
return await readPointsIncentiveReward(this._config, {
|
|
173
|
+
address: this.assertValidAddress(),
|
|
174
|
+
args: [],
|
|
175
|
+
// biome-ignore lint/suspicious/noExplicitAny: Accept any shape of valid wagmi/viem parameters, wagmi does the same thing internally
|
|
176
|
+
...(params as any),
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* A mapping of address to claim status
|
|
182
|
+
*
|
|
183
|
+
* @public
|
|
184
|
+
* @async
|
|
185
|
+
* @param {Address} address
|
|
186
|
+
* @param {?ReadParams} [params]
|
|
187
|
+
* @returns {Promise<boolean>}
|
|
188
|
+
*/
|
|
189
|
+
public async claimed(
|
|
190
|
+
address: Address,
|
|
191
|
+
params?: ReadParams<typeof pointsIncentiveAbi, 'claimed'>,
|
|
192
|
+
) {
|
|
193
|
+
return await readPointsIncentiveClaimed(this._config, {
|
|
194
|
+
address: this.assertValidAddress(),
|
|
195
|
+
args: [address],
|
|
196
|
+
// biome-ignore lint/suspicious/noExplicitAny: Accept any shape of valid wagmi/viem parameters, wagmi does the same thing internally
|
|
197
|
+
...(params as any),
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* The address of the points contract
|
|
203
|
+
*
|
|
204
|
+
* @public
|
|
205
|
+
* @async
|
|
206
|
+
* @param {?ReadParams} [params]
|
|
207
|
+
* @returns {Promise<Address>}
|
|
208
|
+
*/
|
|
209
|
+
public async venue(params?: ReadParams<typeof pointsIncentiveAbi, 'venue'>) {
|
|
210
|
+
return await readPointsIncentiveVenue(this._config, {
|
|
211
|
+
address: this.assertValidAddress(),
|
|
212
|
+
// biome-ignore lint/suspicious/noExplicitAny: Accept any shape of valid wagmi/viem parameters, wagmi does the same thing internally
|
|
213
|
+
...(params as any),
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* The maximum number of claims that can be made (one per address)
|
|
219
|
+
*
|
|
220
|
+
* @public
|
|
221
|
+
* @async
|
|
222
|
+
* @param {?ReadParams} [params]
|
|
223
|
+
* @returns {Promise<bigint>}
|
|
224
|
+
*/
|
|
225
|
+
public async limit(params?: ReadParams<typeof pointsIncentiveAbi, 'limit'>) {
|
|
226
|
+
return await readPointsIncentiveLimit(this._config, {
|
|
227
|
+
address: this.assertValidAddress(),
|
|
228
|
+
// biome-ignore lint/suspicious/noExplicitAny: Accept any shape of valid wagmi/viem parameters, wagmi does the same thing internally
|
|
229
|
+
...(params as any),
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* The selector for the issuance function on the points contract
|
|
235
|
+
*
|
|
236
|
+
* @public
|
|
237
|
+
* @async
|
|
238
|
+
* @param {?ReadParams} [params]
|
|
239
|
+
* @returns {Promise<Hex>}
|
|
240
|
+
*/
|
|
241
|
+
public async selector(
|
|
242
|
+
params?: ReadParams<typeof pointsIncentiveAbi, 'selector'>,
|
|
243
|
+
) {
|
|
244
|
+
return await readPointsIncentiveSelector(this._config, {
|
|
245
|
+
address: this.assertValidAddress(),
|
|
246
|
+
// biome-ignore lint/suspicious/noExplicitAny: Accept any shape of valid wagmi/viem parameters, wagmi does the same thing internally
|
|
247
|
+
...(params as any),
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Claim the incentive
|
|
253
|
+
*
|
|
254
|
+
* @public
|
|
255
|
+
* @async
|
|
256
|
+
* @param {ClaimPayload} payload
|
|
257
|
+
* @param {?WriteParams} [params]
|
|
258
|
+
* @returns {Promise<boolean>} - True if the incentive was successfully claimed
|
|
259
|
+
*/
|
|
260
|
+
protected async claim(
|
|
261
|
+
payload: ClaimPayload,
|
|
262
|
+
params?: WriteParams<typeof pointsIncentiveAbi, 'claim'>,
|
|
263
|
+
) {
|
|
264
|
+
return await this.awaitResult(this.claimRaw(payload, params));
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Claim the incentive
|
|
269
|
+
*
|
|
270
|
+
* @public
|
|
271
|
+
* @async
|
|
272
|
+
* @param {ClaimPayload} payload
|
|
273
|
+
* @param {?WriteParams} [params]
|
|
274
|
+
* @returns {Promise<{ hash: `0x${string}`; result: boolean; }>} - True if the incentive was successfully claimed
|
|
275
|
+
*/
|
|
276
|
+
protected async claimRaw(
|
|
277
|
+
payload: ClaimPayload,
|
|
278
|
+
params?: WriteParams<typeof pointsIncentiveAbi, 'claim'>,
|
|
279
|
+
) {
|
|
280
|
+
const { request, result } = await simulatePointsIncentiveClaim(
|
|
281
|
+
this._config,
|
|
282
|
+
{
|
|
283
|
+
address: this.assertValidAddress(),
|
|
284
|
+
args: [prepareClaimPayload(payload)],
|
|
285
|
+
...this.optionallyAttachAccount(),
|
|
286
|
+
// biome-ignore lint/suspicious/noExplicitAny: Accept any shape of valid wagmi/viem parameters, wagmi does the same thing internally
|
|
287
|
+
...(params as any),
|
|
288
|
+
},
|
|
289
|
+
);
|
|
290
|
+
const hash = await writePointsIncentiveClaim(this._config, request);
|
|
291
|
+
return { hash, result };
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Check if an incentive is claimable.
|
|
296
|
+
* For the POOL strategy, the `bytes data` portion of the payload ignored.
|
|
297
|
+
* The recipient must not have already claimed the incentive.
|
|
298
|
+
*
|
|
299
|
+
* @public
|
|
300
|
+
* @async
|
|
301
|
+
* @param {ClaimPayload} payload
|
|
302
|
+
* @param {?ReadParams} [params]
|
|
303
|
+
* @returns {Promise<boolean>} - True if the incentive is claimable based on the data payload
|
|
304
|
+
*/
|
|
305
|
+
public async isClaimable(
|
|
306
|
+
payload: ClaimPayload,
|
|
307
|
+
params?: ReadParams<typeof pointsIncentiveAbi, 'isClaimable'>,
|
|
308
|
+
) {
|
|
309
|
+
return await readPointsIncentiveIsClaimable(this._config, {
|
|
310
|
+
address: this.assertValidAddress(),
|
|
311
|
+
args: [prepareClaimPayload(payload)],
|
|
312
|
+
// biome-ignore lint/suspicious/noExplicitAny: Accept any shape of valid wagmi/viem parameters, wagmi does the same thing internally
|
|
313
|
+
...(params as any),
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* @inheritdoc
|
|
319
|
+
*
|
|
320
|
+
* @public
|
|
321
|
+
* @param {?PointsIncentivePayload} [_payload]
|
|
322
|
+
* @param {?DeployableOptions} [_options]
|
|
323
|
+
* @returns {GenericDeployableParams}
|
|
324
|
+
*/
|
|
325
|
+
public override buildParameters(
|
|
326
|
+
_payload?: PointsIncentivePayload,
|
|
327
|
+
_options?: DeployableOptions,
|
|
328
|
+
): GenericDeployableParams {
|
|
329
|
+
const [payload, options] = this.validateDeploymentConfig(
|
|
330
|
+
_payload,
|
|
331
|
+
_options,
|
|
332
|
+
);
|
|
333
|
+
return {
|
|
334
|
+
abi: pointsIncentiveAbi,
|
|
335
|
+
bytecode: bytecode as Hex,
|
|
336
|
+
args: [preparePointsIncentivePayload(payload)],
|
|
337
|
+
...this.optionallyAttachAccount(options.account),
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Given a {@link PointsIncentivePayload}, properly encode a `PointsIncentive.InitPayload` for use with {@link PointsIncentive} initialization.
|
|
344
|
+
*
|
|
345
|
+
* @param {PointsIncentivePayload} param0
|
|
346
|
+
* @param {Address} param0.venue - The address of the points contract
|
|
347
|
+
* @param {Hex} param0.selector - The selector for the issuance function on the points contract
|
|
348
|
+
* @param {bigint} param0.reward - The reward amount issued for each claim
|
|
349
|
+
* @param {bigint} param0.limit - The maximum number of claims that can be made (one per address)
|
|
350
|
+
* @returns {*}
|
|
351
|
+
*/
|
|
352
|
+
export const preparePointsIncentivePayload = ({
|
|
353
|
+
venue,
|
|
354
|
+
selector,
|
|
355
|
+
reward,
|
|
356
|
+
limit,
|
|
357
|
+
}: PointsIncentivePayload) => {
|
|
358
|
+
return encodeAbiParameters(
|
|
359
|
+
[
|
|
360
|
+
{ type: 'address', name: 'venue' },
|
|
361
|
+
{ type: 'bytes4', name: 'selector' },
|
|
362
|
+
{ type: 'uint256', name: 'reward' },
|
|
363
|
+
{ type: 'uint256', name: 'limit' },
|
|
364
|
+
],
|
|
365
|
+
[venue, selector, reward, limit],
|
|
366
|
+
);
|
|
367
|
+
};
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { loadFixture } from '@nomicfoundation/hardhat-network-helpers';
|
|
2
|
+
import { isAddress, pad } from 'viem';
|
|
3
|
+
import { beforeAll, describe, expect, test } from 'vitest';
|
|
4
|
+
import { accounts } from '@boostxyz/test/accounts';
|
|
5
|
+
import {
|
|
6
|
+
type Fixtures,
|
|
7
|
+
defaultOptions,
|
|
8
|
+
deployFixtures,
|
|
9
|
+
} from '@boostxyz/test/helpers';
|
|
10
|
+
import { testAccount } from '@boostxyz/test/viem';
|
|
11
|
+
import { SignerValidator } from './SignerValidator';
|
|
12
|
+
|
|
13
|
+
let fixtures: Fixtures;
|
|
14
|
+
|
|
15
|
+
function freshValidator(fixtures: Fixtures) {
|
|
16
|
+
return function freshValidator() {
|
|
17
|
+
// biome-ignore lint/style/noNonNullAssertion: this will never be undefined
|
|
18
|
+
const account = accounts.at(1)!.account;
|
|
19
|
+
return fixtures.registry.initialize(
|
|
20
|
+
crypto.randomUUID(),
|
|
21
|
+
fixtures.core.SignerValidator({
|
|
22
|
+
signers: [defaultOptions.account.address, account],
|
|
23
|
+
validatorCaller: testAccount.address,
|
|
24
|
+
}),
|
|
25
|
+
);
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
describe('SignerValidator', () => {
|
|
30
|
+
beforeAll(async () => {
|
|
31
|
+
fixtures = await loadFixture(deployFixtures(defaultOptions));
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test('can successfully be deployed', async () => {
|
|
35
|
+
const action = new SignerValidator(defaultOptions, {
|
|
36
|
+
signers: [testAccount.address],
|
|
37
|
+
validatorCaller: testAccount.address,
|
|
38
|
+
});
|
|
39
|
+
await action.deploy();
|
|
40
|
+
expect(isAddress(action.assertValidAddress())).toBe(true);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test('initializes successfully', async () => {
|
|
44
|
+
const validator = await loadFixture(freshValidator(fixtures));
|
|
45
|
+
expect(await validator.signers(defaultOptions.account.address)).toBe(true);
|
|
46
|
+
// biome-ignore lint/style/noNonNullAssertion: this will never be undefined
|
|
47
|
+
expect(await validator.signers(accounts.at(1)!.account)).toBe(true);
|
|
48
|
+
// biome-ignore lint/style/noNonNullAssertion: this will never be undefined
|
|
49
|
+
expect(await validator.signers(accounts.at(2)!.account)).toBe(false);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test('can validate hashes', async () => {
|
|
53
|
+
const validator = await loadFixture(freshValidator(fixtures));
|
|
54
|
+
|
|
55
|
+
// Define the input data
|
|
56
|
+
const boostId = 5n;
|
|
57
|
+
const incentiveQuantity = 1;
|
|
58
|
+
const incentiveId = 0n;
|
|
59
|
+
const claimant = '0x24582544C98a86eE59687c4D5B55D78f4FffA666';
|
|
60
|
+
const incentiveData = pad('0xdef456232173821931823712381232131391321934');
|
|
61
|
+
|
|
62
|
+
// biome-ignore lint/style/noNonNullAssertion: this will never be undefined
|
|
63
|
+
const trustedSigner = accounts.at(0)!;
|
|
64
|
+
// biome-ignore lint/style/noNonNullAssertion: this will never be undefined
|
|
65
|
+
const untrustedSigner = accounts.at(2)!;
|
|
66
|
+
|
|
67
|
+
const claimDataPayload = await validator.encodeClaimData({
|
|
68
|
+
signer: trustedSigner,
|
|
69
|
+
incentiveData,
|
|
70
|
+
chainId: defaultOptions.config.chains[0].id,
|
|
71
|
+
incentiveQuantity,
|
|
72
|
+
claimant,
|
|
73
|
+
boostId: boostId,
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
const badClaimDataPayload = await validator.encodeClaimData({
|
|
77
|
+
signer: untrustedSigner,
|
|
78
|
+
incentiveData,
|
|
79
|
+
chainId: defaultOptions.config.chains[0].id,
|
|
80
|
+
incentiveQuantity,
|
|
81
|
+
claimant,
|
|
82
|
+
boostId: boostId,
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
// Validation using trusted signer
|
|
86
|
+
expect(
|
|
87
|
+
await validator.validate({
|
|
88
|
+
boostId: boostId,
|
|
89
|
+
incentiveId: incentiveId,
|
|
90
|
+
claimData: claimDataPayload,
|
|
91
|
+
claimant: claimant,
|
|
92
|
+
}),
|
|
93
|
+
).toBe(true);
|
|
94
|
+
|
|
95
|
+
// Validation using untrusted signer should throw an error
|
|
96
|
+
try {
|
|
97
|
+
await validator.validate({
|
|
98
|
+
boostId: boostId,
|
|
99
|
+
incentiveId: incentiveId,
|
|
100
|
+
claimData: badClaimDataPayload,
|
|
101
|
+
claimant: claimant,
|
|
102
|
+
});
|
|
103
|
+
} catch (e) {
|
|
104
|
+
expect(e).toBeInstanceOf(Error);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
test('will not revalidate the same hash', async () => {
|
|
108
|
+
const validator = await loadFixture(freshValidator(fixtures));
|
|
109
|
+
|
|
110
|
+
// Define the input data
|
|
111
|
+
const boostId = 5n;
|
|
112
|
+
const incentiveQuantity = 1;
|
|
113
|
+
const incentiveId = 0n;
|
|
114
|
+
const claimant = '0x24582544C98a86eE59687c4D5B55D78f4FffA666';
|
|
115
|
+
const incentiveData = pad('0xdef456232173821931823712381232131391321934');
|
|
116
|
+
|
|
117
|
+
// biome-ignore lint/style/noNonNullAssertion: this will never be undefined
|
|
118
|
+
const trustedSigner = accounts.at(0)!;
|
|
119
|
+
|
|
120
|
+
const claimDataPayload = await validator.encodeClaimData({
|
|
121
|
+
signer: trustedSigner,
|
|
122
|
+
incentiveData,
|
|
123
|
+
chainId: defaultOptions.config.chains[0].id,
|
|
124
|
+
incentiveQuantity,
|
|
125
|
+
claimant,
|
|
126
|
+
boostId: boostId,
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
expect(
|
|
130
|
+
await validator.validate({
|
|
131
|
+
boostId,
|
|
132
|
+
incentiveId,
|
|
133
|
+
claimant,
|
|
134
|
+
claimData: claimDataPayload,
|
|
135
|
+
}),
|
|
136
|
+
).toBe(true);
|
|
137
|
+
|
|
138
|
+
// Attempt to validate the same hash again (should throw an error)
|
|
139
|
+
try {
|
|
140
|
+
await validator.validate({
|
|
141
|
+
boostId,
|
|
142
|
+
incentiveId,
|
|
143
|
+
claimData: claimDataPayload,
|
|
144
|
+
claimant,
|
|
145
|
+
});
|
|
146
|
+
} catch (e) {
|
|
147
|
+
expect(e).toBeInstanceOf(Error);
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
test('can set authorized', async () => {
|
|
152
|
+
const validator = await loadFixture(freshValidator(fixtures));
|
|
153
|
+
// biome-ignore lint/style/noNonNullAssertion: this will never be undefined
|
|
154
|
+
const newSigner = accounts.at(2)!.account;
|
|
155
|
+
expect(await validator.signers(newSigner)).toBe(false);
|
|
156
|
+
await validator.setAuthorized([newSigner], [true]);
|
|
157
|
+
expect(await validator.signers(newSigner)).toBe(true);
|
|
158
|
+
});
|
|
159
|
+
});
|