@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.
Files changed (271) hide show
  1. package/dist/Actions/Action.cjs +2 -1
  2. package/dist/Actions/Action.cjs.map +1 -0
  3. package/dist/Actions/Action.d.ts +1 -1
  4. package/dist/Actions/Action.d.ts.map +1 -1
  5. package/dist/Actions/Action.js +14 -12
  6. package/dist/Actions/Action.js.map +1 -0
  7. package/dist/Actions/ContractAction.d.ts +57 -14
  8. package/dist/Actions/ContractAction.d.ts.map +1 -1
  9. package/dist/Actions/ERC721MintAction.d.ts +50 -23
  10. package/dist/Actions/ERC721MintAction.d.ts.map +1 -1
  11. package/dist/Actions/EventAction.cjs +2 -1
  12. package/dist/Actions/EventAction.cjs.map +1 -0
  13. package/dist/Actions/EventAction.d.ts +405 -36
  14. package/dist/Actions/EventAction.d.ts.map +1 -1
  15. package/dist/Actions/EventAction.js +15 -209
  16. package/dist/Actions/EventAction.js.map +1 -0
  17. package/dist/AllowLists/AllowList.cjs +2 -1
  18. package/dist/AllowLists/AllowList.cjs.map +1 -0
  19. package/dist/AllowLists/AllowList.d.ts +6 -5
  20. package/dist/AllowLists/AllowList.d.ts.map +1 -1
  21. package/dist/AllowLists/AllowList.js +46 -22
  22. package/dist/AllowLists/AllowList.js.map +1 -0
  23. package/dist/AllowLists/OpenAllowList.d.ts +423 -0
  24. package/dist/AllowLists/OpenAllowList.d.ts.map +1 -0
  25. package/dist/AllowLists/SimpleAllowList.cjs +2 -1
  26. package/dist/AllowLists/SimpleAllowList.cjs.map +1 -0
  27. package/dist/AllowLists/SimpleAllowList.d.ts +124 -40
  28. package/dist/AllowLists/SimpleAllowList.d.ts.map +1 -1
  29. package/dist/AllowLists/SimpleAllowList.js +77 -77
  30. package/dist/AllowLists/SimpleAllowList.js.map +1 -0
  31. package/dist/AllowLists/SimpleDenyList.cjs +2 -1
  32. package/dist/AllowLists/SimpleDenyList.cjs.map +1 -0
  33. package/dist/AllowLists/SimpleDenyList.d.ts +234 -13
  34. package/dist/AllowLists/SimpleDenyList.d.ts.map +1 -1
  35. package/dist/AllowLists/SimpleDenyList.js +12 -200
  36. package/dist/AllowLists/SimpleDenyList.js.map +1 -0
  37. package/dist/Auth/Auth.cjs +1 -0
  38. package/dist/Auth/Auth.cjs.map +1 -0
  39. package/dist/Auth/Auth.js +1 -0
  40. package/dist/Auth/Auth.js.map +1 -0
  41. package/dist/Auth/PassthroughAuth.cjs +2 -1
  42. package/dist/Auth/PassthroughAuth.cjs.map +1 -0
  43. package/dist/Auth/PassthroughAuth.js +5 -4
  44. package/dist/Auth/PassthroughAuth.js.map +1 -0
  45. package/dist/Boost.cjs +2 -1
  46. package/dist/Boost.cjs.map +1 -0
  47. package/dist/Boost.d.ts +111 -1
  48. package/dist/Boost.d.ts.map +1 -1
  49. package/dist/Boost.js +140 -5
  50. package/dist/Boost.js.map +1 -0
  51. package/dist/BoostCore-3-U1xTQN.cjs +3 -0
  52. package/dist/BoostCore-3-U1xTQN.cjs.map +1 -0
  53. package/dist/BoostCore-DVGBUr2y.js +1477 -0
  54. package/dist/BoostCore-DVGBUr2y.js.map +1 -0
  55. package/dist/BoostCore.cjs +2 -2
  56. package/dist/BoostCore.cjs.map +1 -0
  57. package/dist/BoostCore.d.ts +166 -43
  58. package/dist/BoostCore.d.ts.map +1 -1
  59. package/dist/BoostCore.js +30 -1103
  60. package/dist/BoostCore.js.map +1 -0
  61. package/dist/BoostRegistry.cjs +2 -1
  62. package/dist/BoostRegistry.cjs.map +1 -0
  63. package/dist/BoostRegistry.d.ts +64 -23
  64. package/dist/BoostRegistry.d.ts.map +1 -1
  65. package/dist/BoostRegistry.js +162 -88
  66. package/dist/BoostRegistry.js.map +1 -0
  67. package/dist/Budgets/Budget.cjs +2 -1
  68. package/dist/Budgets/Budget.cjs.map +1 -0
  69. package/dist/Budgets/Budget.d.ts +1 -1
  70. package/dist/Budgets/Budget.d.ts.map +1 -1
  71. package/dist/Budgets/Budget.js +15 -13
  72. package/dist/Budgets/Budget.js.map +1 -0
  73. package/dist/Budgets/ManagedBudget.cjs +2 -1
  74. package/dist/Budgets/ManagedBudget.cjs.map +1 -0
  75. package/dist/Budgets/ManagedBudget.d.ts +78 -188
  76. package/dist/Budgets/ManagedBudget.d.ts.map +1 -1
  77. package/dist/Budgets/ManagedBudget.js +86 -286
  78. package/dist/Budgets/ManagedBudget.js.map +1 -0
  79. package/dist/Budgets/VestingBudget.d.ts +243 -87
  80. package/dist/Budgets/VestingBudget.d.ts.map +1 -1
  81. package/dist/Deployable/Contract.cjs +2 -1
  82. package/dist/Deployable/Contract.cjs.map +1 -0
  83. package/dist/Deployable/Contract.d.ts +4 -5
  84. package/dist/Deployable/Contract.d.ts.map +1 -1
  85. package/dist/Deployable/Contract.js +7 -8
  86. package/dist/Deployable/Contract.js.map +1 -0
  87. package/dist/Deployable/Deployable.cjs +1 -0
  88. package/dist/Deployable/Deployable.cjs.map +1 -0
  89. package/dist/Deployable/Deployable.d.ts +9 -3
  90. package/dist/Deployable/Deployable.d.ts.map +1 -1
  91. package/dist/Deployable/Deployable.js +10 -5
  92. package/dist/Deployable/Deployable.js.map +1 -0
  93. package/dist/Deployable/DeployableTarget.cjs +2 -1
  94. package/dist/Deployable/DeployableTarget.cjs.map +1 -0
  95. package/dist/Deployable/DeployableTarget.d.ts +16 -15
  96. package/dist/Deployable/DeployableTarget.d.ts.map +1 -1
  97. package/dist/Deployable/DeployableTarget.js +49 -42
  98. package/dist/Deployable/DeployableTarget.js.map +1 -0
  99. package/dist/Deployable/DeployableTargetWithRBAC.cjs +2 -0
  100. package/dist/Deployable/DeployableTargetWithRBAC.cjs.map +1 -0
  101. package/dist/Deployable/DeployableTargetWithRBAC.d.ts +179 -0
  102. package/dist/Deployable/DeployableTargetWithRBAC.d.ts.map +1 -0
  103. package/dist/Deployable/DeployableTargetWithRBAC.js +222 -0
  104. package/dist/Deployable/DeployableTargetWithRBAC.js.map +1 -0
  105. package/dist/EventAction-CIPqmAoP.js +1450 -0
  106. package/dist/EventAction-CIPqmAoP.js.map +1 -0
  107. package/dist/EventAction-d-oeqZQs.cjs +2 -0
  108. package/dist/EventAction-d-oeqZQs.cjs.map +1 -0
  109. package/dist/Incentive-Bp8Sez7M.js +298 -0
  110. package/dist/Incentive-Bp8Sez7M.js.map +1 -0
  111. package/dist/Incentive-Djnzseoj.cjs +2 -0
  112. package/dist/Incentive-Djnzseoj.cjs.map +1 -0
  113. package/dist/Incentives/AllowListIncentive.cjs +2 -1
  114. package/dist/Incentives/AllowListIncentive.cjs.map +1 -0
  115. package/dist/Incentives/AllowListIncentive.d.ts +49 -19
  116. package/dist/Incentives/AllowListIncentive.d.ts.map +1 -1
  117. package/dist/Incentives/AllowListIncentive.js +50 -34
  118. package/dist/Incentives/AllowListIncentive.js.map +1 -0
  119. package/dist/Incentives/CGDAIncentive.cjs +2 -1
  120. package/dist/Incentives/CGDAIncentive.cjs.map +1 -0
  121. package/dist/Incentives/CGDAIncentive.d.ts +118 -22
  122. package/dist/Incentives/CGDAIncentive.d.ts.map +1 -1
  123. package/dist/Incentives/CGDAIncentive.js +67 -42
  124. package/dist/Incentives/CGDAIncentive.js.map +1 -0
  125. package/dist/Incentives/ERC1155Incentive.d.ts +99 -38
  126. package/dist/Incentives/ERC1155Incentive.d.ts.map +1 -1
  127. package/dist/Incentives/ERC20Incentive.cjs +2 -1
  128. package/dist/Incentives/ERC20Incentive.cjs.map +1 -0
  129. package/dist/Incentives/ERC20Incentive.d.ts +73 -29
  130. package/dist/Incentives/ERC20Incentive.d.ts.map +1 -1
  131. package/dist/Incentives/ERC20Incentive.js +71 -48
  132. package/dist/Incentives/ERC20Incentive.js.map +1 -0
  133. package/dist/Incentives/ERC20VariableCriteriaIncentive.d.ts +523 -0
  134. package/dist/Incentives/ERC20VariableCriteriaIncentive.d.ts.map +1 -0
  135. package/dist/Incentives/ERC20VariableIncentive.d.ts +65 -28
  136. package/dist/Incentives/ERC20VariableIncentive.d.ts.map +1 -1
  137. package/dist/Incentives/Incentive.cjs +2 -1
  138. package/dist/Incentives/Incentive.cjs.map +1 -0
  139. package/dist/Incentives/Incentive.d.ts +4 -7
  140. package/dist/Incentives/Incentive.d.ts.map +1 -1
  141. package/dist/Incentives/Incentive.js +17 -278
  142. package/dist/Incentives/Incentive.js.map +1 -0
  143. package/dist/Incentives/PointsIncentive.cjs +2 -1
  144. package/dist/Incentives/PointsIncentive.cjs.map +1 -0
  145. package/dist/Incentives/PointsIncentive.d.ts +65 -21
  146. package/dist/Incentives/PointsIncentive.d.ts.map +1 -1
  147. package/dist/Incentives/PointsIncentive.js +57 -36
  148. package/dist/Incentives/PointsIncentive.js.map +1 -0
  149. package/dist/SimpleDenyList-BwfNjRsg.cjs +2 -0
  150. package/dist/SimpleDenyList-BwfNjRsg.cjs.map +1 -0
  151. package/dist/SimpleDenyList-Cn5WpNn0.js +132 -0
  152. package/dist/SimpleDenyList-Cn5WpNn0.js.map +1 -0
  153. package/dist/Validators/SignerValidator.cjs +2 -1
  154. package/dist/Validators/SignerValidator.cjs.map +1 -0
  155. package/dist/Validators/SignerValidator.d.ts +310 -17
  156. package/dist/Validators/SignerValidator.d.ts.map +1 -1
  157. package/dist/Validators/SignerValidator.js +165 -36
  158. package/dist/Validators/SignerValidator.js.map +1 -0
  159. package/dist/Validators/Validator.cjs +2 -1
  160. package/dist/Validators/Validator.cjs.map +1 -0
  161. package/dist/Validators/Validator.d.ts +2 -2
  162. package/dist/Validators/Validator.d.ts.map +1 -1
  163. package/dist/Validators/Validator.js +12 -10
  164. package/dist/Validators/Validator.js.map +1 -0
  165. package/dist/claiming.cjs +2 -0
  166. package/dist/claiming.cjs.map +1 -0
  167. package/dist/claiming.d.ts +43 -0
  168. package/dist/claiming.d.ts.map +1 -0
  169. package/dist/claiming.js +17 -0
  170. package/dist/claiming.js.map +1 -0
  171. package/dist/componentInterfaces-D09mhzxO.cjs +2 -0
  172. package/dist/componentInterfaces-D09mhzxO.cjs.map +1 -0
  173. package/dist/componentInterfaces-RXBMI5yH.js +14 -0
  174. package/dist/componentInterfaces-RXBMI5yH.js.map +1 -0
  175. package/dist/deployments-BM42vImE.js +43 -0
  176. package/dist/deployments-BM42vImE.js.map +1 -0
  177. package/dist/deployments-CMdF5uEC.cjs +2 -0
  178. package/dist/deployments-CMdF5uEC.cjs.map +1 -0
  179. package/dist/deployments.json +41 -0
  180. package/dist/errors.cjs +2 -1
  181. package/dist/errors.cjs.map +1 -0
  182. package/dist/errors.d.ts +403 -1
  183. package/dist/errors.d.ts.map +1 -1
  184. package/dist/errors.js +285 -39
  185. package/dist/errors.js.map +1 -0
  186. package/dist/generated-B0tk-c9b.cjs +3 -0
  187. package/dist/generated-B0tk-c9b.cjs.map +1 -0
  188. package/dist/{generated-x_abr3Yv.js → generated-B7VaSah4.js} +2058 -2541
  189. package/dist/generated-B7VaSah4.js.map +1 -0
  190. package/dist/index.cjs +2 -1
  191. package/dist/index.cjs.map +1 -0
  192. package/dist/index.d.ts +10 -9
  193. package/dist/index.d.ts.map +1 -1
  194. package/dist/index.js +143 -1353
  195. package/dist/index.js.map +1 -0
  196. package/dist/transfers.cjs +2 -0
  197. package/dist/transfers.cjs.map +1 -0
  198. package/dist/transfers.d.ts +198 -0
  199. package/dist/transfers.d.ts.map +1 -0
  200. package/dist/transfers.js +84 -0
  201. package/dist/transfers.js.map +1 -0
  202. package/dist/utils.cjs +2 -1
  203. package/dist/utils.cjs.map +1 -0
  204. package/dist/utils.d.ts +26 -1350
  205. package/dist/utils.d.ts.map +1 -1
  206. package/dist/utils.js +38 -636
  207. package/dist/utils.js.map +1 -0
  208. package/package.json +37 -11
  209. package/src/Actions/Action.test.ts +79 -0
  210. package/src/Actions/Action.ts +61 -0
  211. package/src/Actions/ContractAction.test.ts +197 -0
  212. package/src/Actions/ContractAction.ts +300 -0
  213. package/src/Actions/ERC721MintAction.test.ts +112 -0
  214. package/src/Actions/ERC721MintAction.ts +291 -0
  215. package/src/Actions/EventAction.test.ts +787 -0
  216. package/src/Actions/EventAction.ts +1214 -0
  217. package/src/AllowLists/AllowList.test.ts +64 -0
  218. package/src/AllowLists/AllowList.ts +62 -0
  219. package/src/AllowLists/OpenAllowList.test.ts +40 -0
  220. package/src/AllowLists/OpenAllowList.ts +45 -0
  221. package/src/AllowLists/SimpleAllowList.test.ts +52 -0
  222. package/src/AllowLists/SimpleAllowList.ts +262 -0
  223. package/src/AllowLists/SimpleDenyList.test.ts +52 -0
  224. package/src/AllowLists/SimpleDenyList.ts +250 -0
  225. package/src/Auth/Auth.ts +11 -0
  226. package/src/Auth/PassthroughAuth.test.ts +12 -0
  227. package/src/Auth/PassthroughAuth.ts +80 -0
  228. package/src/Boost.ts +309 -0
  229. package/src/BoostCore.test.ts +827 -0
  230. package/src/BoostCore.ts +1447 -0
  231. package/src/BoostRegistry.ts +543 -0
  232. package/src/Budgets/Budget.test.ts +27 -0
  233. package/src/Budgets/Budget.ts +60 -0
  234. package/src/Budgets/ManagedBudget.test.ts +217 -0
  235. package/src/Budgets/ManagedBudget.ts +534 -0
  236. package/src/Budgets/VestingBudget.test.ts +123 -0
  237. package/src/Budgets/VestingBudget.ts +530 -0
  238. package/src/Deployable/Contract.ts +228 -0
  239. package/src/Deployable/Deployable.ts +250 -0
  240. package/src/Deployable/DeployableTarget.ts +234 -0
  241. package/src/Deployable/DeployableTargetWithRBAC.ts +323 -0
  242. package/src/Incentives/AllowListIncentive.test.ts +143 -0
  243. package/src/Incentives/AllowListIncentive.ts +336 -0
  244. package/src/Incentives/CGDAIncentive.test.ts +132 -0
  245. package/src/Incentives/CGDAIncentive.ts +470 -0
  246. package/src/Incentives/ERC1155Incentive.test.ts +87 -0
  247. package/src/Incentives/ERC1155Incentive.ts +465 -0
  248. package/src/Incentives/ERC20Incentive.test.ts +130 -0
  249. package/src/Incentives/ERC20Incentive.ts +484 -0
  250. package/src/Incentives/ERC20VariableCriteriaIncentive.test.ts +184 -0
  251. package/src/Incentives/ERC20VariableCriteriaIncentive.ts +309 -0
  252. package/src/Incentives/ERC20VariableIncentive.test.ts +136 -0
  253. package/src/Incentives/ERC20VariableIncentive.ts +422 -0
  254. package/src/Incentives/Incentive.test.ts +92 -0
  255. package/src/Incentives/Incentive.ts +86 -0
  256. package/src/Incentives/PointsIncentive.test.ts +139 -0
  257. package/src/Incentives/PointsIncentive.ts +367 -0
  258. package/src/Validators/SignerValidator.test.ts +159 -0
  259. package/src/Validators/SignerValidator.ts +683 -0
  260. package/src/Validators/Validator.test.ts +21 -0
  261. package/src/Validators/Validator.ts +55 -0
  262. package/src/claiming.ts +56 -0
  263. package/src/errors.ts +844 -0
  264. package/src/index.test.ts +122 -0
  265. package/src/index.ts +58 -0
  266. package/src/transfers.ts +284 -0
  267. package/src/utils.test.ts +44 -0
  268. package/src/utils.ts +247 -0
  269. package/dist/Budgets/SimpleBudget.d.ts +0 -793
  270. package/dist/Budgets/SimpleBudget.d.ts.map +0 -1
  271. package/dist/generated-BaaleHW-.cjs +0 -2
@@ -0,0 +1,827 @@
1
+ import { loadFixture } from '@nomicfoundation/hardhat-toolbox-viem/network-helpers';
2
+ import { pad, parseEther, zeroAddress } from 'viem';
3
+ import { beforeAll, beforeEach, describe, expect, test, vi } from 'vitest';
4
+ import {
5
+ type BudgetFixtures,
6
+ type Fixtures,
7
+ defaultOptions,
8
+ deployFixtures,
9
+ freshBoost,
10
+ fundBudget,
11
+ makeMockEventActionPayload,
12
+ } from '@boostxyz/test/helpers';
13
+ import { ContractAction } from './Actions/ContractAction';
14
+ import type { ERC20Incentive } from './Incentives/ERC20Incentive';
15
+ import { StrategyType } from './claiming';
16
+ import { IncentiveNotCloneableError } from './errors';
17
+ import { bytes4 } from './utils';
18
+ import { BOOST_CORE_CLAIM_FEE } from './BoostCore';
19
+ import { accounts } from '@boostxyz/test/accounts';
20
+
21
+ let fixtures: Fixtures, budgets: BudgetFixtures;
22
+
23
+ describe('BoostCore', () => {
24
+ beforeAll(async () => {
25
+ fixtures = await loadFixture(deployFixtures(defaultOptions));
26
+ });
27
+ beforeEach(async () => {
28
+ budgets = await loadFixture(fundBudget(defaultOptions, fixtures));
29
+ });
30
+
31
+ test('can get the total number of boosts', async () => {
32
+ const { core } = fixtures;
33
+
34
+ const { budget, erc20 } = budgets;
35
+ await core.createBoost({
36
+ protocolFee: 1n,
37
+ referralFee: 2n,
38
+ maxParticipants: 100n,
39
+ budget: budget,
40
+ action: core.EventAction(
41
+ makeMockEventActionPayload(
42
+ core.assertValidAddress(),
43
+ erc20.assertValidAddress(),
44
+ ),
45
+ ),
46
+ validator: core.SignerValidator({
47
+ signers: [defaultOptions.account.address],
48
+ validatorCaller: defaultOptions.account.address,
49
+ }),
50
+ allowList: core.SimpleAllowList({
51
+ owner: defaultOptions.account.address,
52
+ allowed: [defaultOptions.account.address],
53
+ }),
54
+ incentives: [
55
+ core.ERC20Incentive({
56
+ asset: erc20.assertValidAddress(),
57
+ reward: parseEther('1'),
58
+ limit: 100n,
59
+ strategy: StrategyType.POOL,
60
+ }),
61
+ ],
62
+ });
63
+ expect(await core.getBoostCount()).toBe(1n);
64
+ });
65
+
66
+ test('can successfully create a boost using all base contract implementations', async () => {
67
+ const { core } = fixtures;
68
+ const { budget, erc20 } = budgets;
69
+ const boost = await core.createBoost({
70
+ protocolFee: 1n,
71
+ referralFee: 2n,
72
+ maxParticipants: 100n,
73
+ budget: budget,
74
+ action: core.EventAction(
75
+ makeMockEventActionPayload(
76
+ core.assertValidAddress(),
77
+ erc20.assertValidAddress(),
78
+ ),
79
+ ),
80
+ validator: core.SignerValidator({
81
+ signers: [defaultOptions.account.address],
82
+ validatorCaller: defaultOptions.account.address,
83
+ }),
84
+ allowList: core.SimpleAllowList({
85
+ owner: defaultOptions.account.address,
86
+ allowed: [defaultOptions.account.address],
87
+ }),
88
+ incentives: [
89
+ core.ERC20Incentive({
90
+ asset: erc20.assertValidAddress(),
91
+ reward: parseEther('1'),
92
+ limit: 100n,
93
+ strategy: StrategyType.POOL,
94
+ }),
95
+ ],
96
+ });
97
+ const onChainBoost = await core.readBoost(boost.id);
98
+
99
+ expect(boost.owner).toBe(onChainBoost.owner);
100
+ expect(boost.protocolFee).toBe(onChainBoost.protocolFee);
101
+ expect(boost.referralFee).toBe(onChainBoost.referralFee);
102
+ expect(boost.maxParticipants).toBe(onChainBoost.maxParticipants);
103
+
104
+ expect(boost.action.address).toBe(onChainBoost.action);
105
+ // just get some type safety here
106
+ if (boost.action instanceof ContractAction === false) return;
107
+ expect(await boost.action.chainId()).toBe(BigInt(31_337));
108
+ expect((await boost.action.target()).toLowerCase()).toBe(
109
+ core.assertValidAddress().toLowerCase(),
110
+ );
111
+ expect(await boost.action.selector()).toBe('0xdeadbeef');
112
+ expect(await boost.action.value()).toBe(0n);
113
+
114
+ expect(boost.validator.address?.toLowerCase()).toBe(
115
+ onChainBoost.validator.toLowerCase(),
116
+ );
117
+ expect(await boost.validator.signers(defaultOptions.account.address)).toBe(
118
+ true,
119
+ );
120
+
121
+ expect(boost.allowList.address?.toLowerCase()).toBe(
122
+ onChainBoost.allowList.toLowerCase(),
123
+ );
124
+ expect(
125
+ await boost.allowList.isAllowed(defaultOptions.account.address),
126
+ ).toBe(true);
127
+ expect(await boost.allowList.isAllowed(zeroAddress)).toBe(false);
128
+
129
+ expect(boost.budget.address?.toLowerCase()).toBe(
130
+ onChainBoost.budget.toLowerCase(),
131
+ );
132
+ expect(
133
+ await boost.budget.isAuthorized(defaultOptions.account.address),
134
+ ).toBe(true);
135
+
136
+ expect(boost.incentives.length).toBe(onChainBoost.incentives.length);
137
+ const incentive = boost.incentives.at(0) as ERC20Incentive;
138
+ expect(incentive.address?.toLowerCase()).toBe(
139
+ onChainBoost.incentives.at(0)?.toLowerCase(),
140
+ );
141
+ expect((await incentive.asset()).toLowerCase()).toBe(
142
+ erc20.address?.toLowerCase(),
143
+ );
144
+ expect(await incentive.currentReward()).toBe(parseEther('1'));
145
+ expect(await incentive.limit()).toBe(100n);
146
+ expect(await incentive.claims()).toBe(0n);
147
+ });
148
+
149
+ test('can read the raw on chain representation of a boost', async () => {
150
+ const { core } = fixtures;
151
+ const { budget, erc20 } = budgets;
152
+ const _boost = await core.createBoost({
153
+ protocolFee: 1n,
154
+ referralFee: 2n,
155
+ maxParticipants: 100n,
156
+ budget: budget,
157
+ action: core.EventAction(
158
+ makeMockEventActionPayload(
159
+ core.assertValidAddress(),
160
+ erc20.assertValidAddress(),
161
+ ),
162
+ ),
163
+ validator: core.SignerValidator({
164
+ signers: [defaultOptions.account.address],
165
+ validatorCaller: defaultOptions.account.address,
166
+ }),
167
+ allowList: core.SimpleAllowList({
168
+ owner: defaultOptions.account.address,
169
+ allowed: [defaultOptions.account.address],
170
+ }),
171
+ incentives: [
172
+ core.ERC20Incentive({
173
+ asset: erc20.assertValidAddress(),
174
+ reward: parseEther('1'),
175
+ limit: 100n,
176
+ strategy: StrategyType.POOL,
177
+ }),
178
+ ],
179
+ });
180
+ const boost = await core.readBoost(_boost.id);
181
+ expect(boost.protocolFee).toBe(1001n);
182
+ expect(boost.referralFee).toBe(1002n);
183
+ expect(boost.maxParticipants).toBe(100n);
184
+ expect(boost.budget).toBe(_boost.budget.assertValidAddress());
185
+ expect(boost.action).toBe(_boost.action.assertValidAddress());
186
+ expect(boost.validator).toBe(_boost.validator.assertValidAddress());
187
+ expect(boost.allowList).toBe(_boost.allowList.assertValidAddress());
188
+ expect(boost.incentives.at(0)).toBe(
189
+ _boost.incentives.at(0)?.assertValidAddress(),
190
+ );
191
+ });
192
+
193
+ test('can reuse an existing action', async () => {
194
+ const { core } = fixtures;
195
+ const { budget, erc20 } = budgets;
196
+
197
+ // allocate more funds to the budget
198
+ await erc20.mint(defaultOptions.account.address, parseEther('100'));
199
+ await erc20.approve(budget.assertValidAddress(), parseEther('100'));
200
+ await budget.allocate({
201
+ amount: parseEther('100'),
202
+ asset: erc20.assertValidAddress(),
203
+ target: defaultOptions.account.address,
204
+ });
205
+
206
+ const _boost = await core.createBoost({
207
+ budget: budget,
208
+ action: core.EventAction(
209
+ makeMockEventActionPayload(
210
+ core.assertValidAddress(),
211
+ erc20.assertValidAddress(),
212
+ ),
213
+ ),
214
+ validator: core.SignerValidator({
215
+ signers: [defaultOptions.account.address],
216
+ validatorCaller: defaultOptions.account.address,
217
+ }),
218
+ allowList: core.SimpleAllowList({
219
+ owner: defaultOptions.account.address,
220
+ allowed: [defaultOptions.account.address],
221
+ }),
222
+ incentives: [
223
+ core.ERC20Incentive({
224
+ asset: erc20.assertValidAddress(),
225
+ reward: parseEther('1'),
226
+ limit: 100n,
227
+ strategy: StrategyType.POOL,
228
+ }),
229
+ ],
230
+ });
231
+ const boost = await core.createBoost({
232
+ budget: budget,
233
+ action: core.EventAction(_boost.action.assertValidAddress(), false),
234
+ validator: core.SignerValidator({
235
+ signers: [defaultOptions.account.address],
236
+ validatorCaller: defaultOptions.account.address,
237
+ }),
238
+ allowList: core.SimpleAllowList({
239
+ owner: defaultOptions.account.address,
240
+ allowed: [defaultOptions.account.address],
241
+ }),
242
+ incentives: [
243
+ core.ERC20Incentive({
244
+ asset: erc20.assertValidAddress(),
245
+ reward: parseEther('1'),
246
+ limit: 100n,
247
+ strategy: StrategyType.POOL,
248
+ }),
249
+ ],
250
+ });
251
+ const onChainBoost = await core.readBoost(boost.id);
252
+ expect(onChainBoost.action).toBe(_boost.action.assertValidAddress());
253
+ });
254
+
255
+ test('can reuse an existing validator', async () => {
256
+ const { core } = fixtures;
257
+ const { budget, erc20 } = budgets;
258
+
259
+ // allocate more erc20 funds to the budget from the owning accound
260
+ await erc20.mint(defaultOptions.account.address, parseEther('100'));
261
+ await erc20.approve(budget.assertValidAddress(), parseEther('100'));
262
+ await budget.allocate({
263
+ amount: parseEther('100'),
264
+ asset: erc20.assertValidAddress(),
265
+ target: defaultOptions.account.address,
266
+ });
267
+
268
+ const _boost = await core.createBoost({
269
+ budget: budget,
270
+ action: core.EventAction(
271
+ makeMockEventActionPayload(
272
+ core.assertValidAddress(),
273
+ erc20.assertValidAddress(),
274
+ ),
275
+ ),
276
+ validator: core.SignerValidator({
277
+ signers: [defaultOptions.account.address],
278
+ validatorCaller: defaultOptions.account.address,
279
+ }),
280
+ allowList: core.SimpleAllowList({
281
+ owner: defaultOptions.account.address,
282
+ allowed: [defaultOptions.account.address],
283
+ }),
284
+ incentives: [
285
+ core.ERC20Incentive({
286
+ asset: erc20.assertValidAddress(),
287
+ reward: parseEther('1'),
288
+ limit: 100n,
289
+ strategy: StrategyType.POOL,
290
+ }),
291
+ ],
292
+ });
293
+ const boost = await core.createBoost({
294
+ budget: budget,
295
+ action: core.EventAction(
296
+ makeMockEventActionPayload(
297
+ core.assertValidAddress(),
298
+ erc20.assertValidAddress(),
299
+ ),
300
+ ),
301
+ validator: core.SignerValidator(
302
+ _boost.validator.assertValidAddress(),
303
+ false,
304
+ ),
305
+ allowList: core.SimpleAllowList({
306
+ owner: defaultOptions.account.address,
307
+ allowed: [defaultOptions.account.address],
308
+ }),
309
+ incentives: [
310
+ core.ERC20Incentive({
311
+ asset: erc20.assertValidAddress(),
312
+ reward: parseEther('1'),
313
+ limit: 100n,
314
+ strategy: StrategyType.POOL,
315
+ }),
316
+ ],
317
+ });
318
+ const onChainBoost = await core.readBoost(boost.id);
319
+ expect(onChainBoost.validator).toBe(_boost.validator.assertValidAddress());
320
+ });
321
+
322
+ test('can reuse an existing allowlist', async () => {
323
+ const { core } = fixtures;
324
+ const { budget, erc20 } = budgets;
325
+
326
+ // allocate more erc20 funds to the budget from the owning accound
327
+ await erc20.mint(defaultOptions.account.address, parseEther('100'));
328
+ await erc20.approve(budget.assertValidAddress(), parseEther('100'));
329
+ await budget.allocate({
330
+ amount: parseEther('100'),
331
+ asset: erc20.assertValidAddress(),
332
+ target: defaultOptions.account.address,
333
+ });
334
+
335
+ const _boost = await core.createBoost({
336
+ budget: budget,
337
+ action: core.EventAction(
338
+ makeMockEventActionPayload(
339
+ core.assertValidAddress(),
340
+ erc20.assertValidAddress(),
341
+ ),
342
+ ),
343
+ validator: core.SignerValidator({
344
+ signers: [defaultOptions.account.address],
345
+ validatorCaller: defaultOptions.account.address,
346
+ }),
347
+ allowList: core.SimpleAllowList({
348
+ owner: defaultOptions.account.address,
349
+ allowed: [defaultOptions.account.address],
350
+ }),
351
+ incentives: [
352
+ core.ERC20Incentive({
353
+ asset: erc20.assertValidAddress(),
354
+ reward: parseEther('1'),
355
+ limit: 100n,
356
+ strategy: StrategyType.POOL,
357
+ }),
358
+ ],
359
+ });
360
+ const boost = await core.createBoost({
361
+ budget: budget,
362
+ action: core.EventAction(
363
+ makeMockEventActionPayload(
364
+ core.assertValidAddress(),
365
+ erc20.assertValidAddress(),
366
+ ),
367
+ ),
368
+ validator: core.SignerValidator({
369
+ signers: [defaultOptions.account.address],
370
+ validatorCaller: defaultOptions.account.address,
371
+ }),
372
+ allowList: core.SimpleAllowList(
373
+ _boost.allowList.assertValidAddress(),
374
+ false,
375
+ ),
376
+ incentives: [
377
+ core.ERC20Incentive({
378
+ asset: erc20.assertValidAddress(),
379
+ reward: parseEther('1'),
380
+ limit: 100n,
381
+ strategy: StrategyType.POOL,
382
+ }),
383
+ ],
384
+ });
385
+ const onChainBoost = await core.readBoost(boost.id);
386
+ expect(onChainBoost.allowList).toBe(_boost.allowList.assertValidAddress());
387
+ });
388
+
389
+ test('cannot reuse an existing incentive', async () => {
390
+ const { core } = fixtures;
391
+ const { budget, erc20 } = budgets;
392
+
393
+ // allocate more erc20 funds to the budget from the owning accound
394
+ await erc20.mint(defaultOptions.account.address, parseEther('100'));
395
+ await erc20.approve(budget.assertValidAddress(), parseEther('100'));
396
+ await budget.allocate({
397
+ amount: parseEther('100'),
398
+ asset: erc20.assertValidAddress(),
399
+ target: defaultOptions.account.address,
400
+ });
401
+
402
+ const incentive = core.ERC20Incentive({
403
+ asset: erc20.assertValidAddress(),
404
+ reward: parseEther('1'),
405
+ limit: 100n,
406
+ strategy: StrategyType.POOL,
407
+ });
408
+ const _boost = await core.createBoost({
409
+ budget: budget,
410
+ action: core.EventAction(
411
+ makeMockEventActionPayload(
412
+ core.assertValidAddress(),
413
+ erc20.assertValidAddress(),
414
+ ),
415
+ ),
416
+ validator: core.SignerValidator({
417
+ signers: [defaultOptions.account.address],
418
+ validatorCaller: defaultOptions.account.address,
419
+ }),
420
+ allowList: core.SimpleAllowList({
421
+ owner: defaultOptions.account.address,
422
+ allowed: [defaultOptions.account.address],
423
+ }),
424
+ incentives: [incentive],
425
+ });
426
+ try {
427
+ await core.createBoost({
428
+ budget: budget,
429
+ action: core.EventAction(
430
+ makeMockEventActionPayload(
431
+ core.assertValidAddress(),
432
+ erc20.assertValidAddress(),
433
+ ),
434
+ ),
435
+ validator: core.SignerValidator({
436
+ signers: [defaultOptions.account.address],
437
+ validatorCaller: defaultOptions.account.address,
438
+ }),
439
+ allowList: core.SimpleAllowList({
440
+ owner: defaultOptions.account.address,
441
+ allowed: [defaultOptions.account.address],
442
+ }),
443
+ incentives: [incentive],
444
+ });
445
+ } catch (e) {
446
+ expect(e).toBeInstanceOf(IncentiveNotCloneableError);
447
+ }
448
+ });
449
+
450
+ test('can offer multiple incentives', async () => {
451
+ const { registry, core } = fixtures;
452
+ const { budget, erc20, points, erc1155 } = budgets;
453
+ const allowList = await registry.initialize(
454
+ 'SharedAllowList',
455
+ core.SimpleAllowList({
456
+ owner: defaultOptions.account.address,
457
+ allowed: [defaultOptions.account.address],
458
+ }),
459
+ );
460
+
461
+ const erc20Incentive = core.ERC20Incentive({
462
+ asset: erc20.assertValidAddress(),
463
+ reward: 1n,
464
+ limit: 10n,
465
+ strategy: StrategyType.POOL,
466
+ });
467
+ // const erc1155Incentive = core.ERC1155Incentive({
468
+ // asset: erc1155.assertValidAddress(),
469
+ // strategy: ERC1155StrategyType.POOL,
470
+ // limit: 1n,
471
+ // tokenId: 1n,
472
+ // extraData: '0x',
473
+ // });
474
+ const cgdaIncentive = core.CGDAIncentive({
475
+ asset: erc20.assertValidAddress(),
476
+ initialReward: 1n,
477
+ totalBudget: 10n,
478
+ rewardBoost: 1n,
479
+ rewardDecay: 1n,
480
+ });
481
+ const allowListIncentive = core.AllowListIncentive({
482
+ allowList: allowList.assertValidAddress(),
483
+ limit: 5n,
484
+ });
485
+ const pointsIncentive = core.PointsIncentive({
486
+ venue: points.assertValidAddress(),
487
+ selector: bytes4('issue(address,uint256)'),
488
+ reward: 1n,
489
+ limit: 10n,
490
+ });
491
+
492
+ await core.createBoost({
493
+ protocolFee: 1n,
494
+ referralFee: 2n,
495
+ maxParticipants: 100n,
496
+ budget: budget,
497
+ action: core.EventAction(
498
+ makeMockEventActionPayload(
499
+ core.assertValidAddress(),
500
+ erc20.assertValidAddress(),
501
+ ),
502
+ ),
503
+ validator: core.SignerValidator({
504
+ signers: [defaultOptions.account.address],
505
+ validatorCaller: defaultOptions.account.address,
506
+ }),
507
+ allowList: core.SimpleAllowList(allowList.assertValidAddress()),
508
+ incentives: [
509
+ // erc1155Incentive,
510
+ erc20Incentive,
511
+ cgdaIncentive,
512
+ allowListIncentive,
513
+ pointsIncentive,
514
+ ],
515
+ });
516
+ expect(await erc20Incentive.reward()).toEqual(1n);
517
+ expect(await erc20Incentive.limit()).toEqual(10n);
518
+ expect((await cgdaIncentive.asset()).toLowerCase()).toEqual(
519
+ erc20.address?.toLowerCase(),
520
+ );
521
+ expect(await cgdaIncentive.currentReward()).toEqual(1n);
522
+ expect(
523
+ await (await allowListIncentive.allowList()).isAllowed(
524
+ defaultOptions.account.address,
525
+ ),
526
+ ).toEqual(true);
527
+ expect(await pointsIncentive.reward()).toEqual(1n);
528
+ expect(await pointsIncentive.currentReward()).toEqual(1n);
529
+ expect(await pointsIncentive.limit()).toEqual(10n);
530
+ });
531
+
532
+ test('can get the protocol fee', async () => {
533
+ const { core } = fixtures;
534
+
535
+ expect(await core.protocolFee()).toBe(1000n);
536
+ });
537
+
538
+ test('can get the protocol fee receiver', async () => {
539
+ const { core } = fixtures;
540
+
541
+ expect(await core.protocolFeeReceiver()).toBe(
542
+ defaultOptions.account.address,
543
+ );
544
+ });
545
+
546
+ test('can set the protocol fee receiver', async () => {
547
+ const { core } = fixtures;
548
+
549
+ await core.setProcolFeeReceiver(zeroAddress);
550
+
551
+ expect(await core.protocolFeeReceiver()).toBe(zeroAddress);
552
+ });
553
+
554
+ test('can get the claim fee', async () => {
555
+ const { core } = fixtures;
556
+
557
+ expect(await core.claimFee()).toBe(75000000000000n);
558
+ });
559
+
560
+ test('can set the claim fee', async () => {
561
+ const { core } = fixtures;
562
+
563
+ await core.setClaimFee(100n);
564
+
565
+ expect(await core.claimFee()).toBe(100n);
566
+ });
567
+
568
+ test('binds all actions, budgets, allowlists, incentives, and validators to reuse core options and account', () => {
569
+ const { core } = fixtures;
570
+
571
+ // const contractAction = core.ContractAction(zeroAddress);
572
+ // expect(contractAction._config).toEqual(defaultOptions.config);
573
+ // expect(contractAction._account).toEqual(defaultOptions.account);
574
+
575
+ // const erc721MintAction = core.ERC721MintAction(zeroAddress);
576
+ // expect(erc721MintAction._config).toEqual(defaultOptions.config);
577
+ // expect(erc721MintAction._account).toEqual(defaultOptions.account);
578
+
579
+ const eventAction = core.EventAction(zeroAddress);
580
+ expect(eventAction._config).toEqual(defaultOptions.config);
581
+ expect(eventAction._account).toEqual(defaultOptions.account);
582
+
583
+ const allowList = core.SimpleAllowList(zeroAddress);
584
+ expect(allowList._config).toEqual(defaultOptions.config);
585
+ expect(allowList._account).toEqual(defaultOptions.account);
586
+
587
+ const denyList = core.SimpleDenyList(zeroAddress);
588
+ expect(denyList._config).toEqual(defaultOptions.config);
589
+ expect(denyList._account).toEqual(defaultOptions.account);
590
+
591
+ const managedBudget = core.ManagedBudget(zeroAddress);
592
+ expect(managedBudget._config).toEqual(defaultOptions.config);
593
+ expect(managedBudget._account).toEqual(defaultOptions.account);
594
+
595
+ // const simpleBudget = core.SimpleBudget(zeroAddress);
596
+ // expect(simpleBudget._config).toEqual(defaultOptions.config);
597
+ // expect(simpleBudget._account).toEqual(defaultOptions.account);
598
+
599
+ // const vestingBudget = core.VestingBudget(zeroAddress);
600
+ // expect(vestingBudget._config).toEqual(defaultOptions.config);
601
+ // expect(vestingBudget._account).toEqual(defaultOptions.account);
602
+
603
+ const allowListIncentive = core.AllowListIncentive({
604
+ allowList: zeroAddress,
605
+ limit: 0n,
606
+ });
607
+ expect(allowListIncentive._config).toEqual(defaultOptions.config);
608
+ expect(allowListIncentive._account).toEqual(defaultOptions.account);
609
+
610
+ const cgdaIncentive = core.CGDAIncentive({
611
+ asset: zeroAddress,
612
+ initialReward: 0n,
613
+ rewardDecay: 0n,
614
+ rewardBoost: 0n,
615
+ totalBudget: 0n,
616
+ });
617
+ expect(cgdaIncentive._config).toEqual(defaultOptions.config);
618
+ expect(cgdaIncentive._account).toEqual(defaultOptions.account);
619
+
620
+ const erc20Incentive = core.ERC20Incentive({
621
+ asset: zeroAddress,
622
+ strategy: 0,
623
+ reward: 0n,
624
+ limit: 0n,
625
+ });
626
+ expect(erc20Incentive._config).toEqual(defaultOptions.config);
627
+ expect(erc20Incentive._account).toEqual(defaultOptions.account);
628
+
629
+ const erc20VariableIncentive = core.ERC20VariableIncentive({
630
+ asset: zeroAddress,
631
+ reward: 0n,
632
+ limit: 0n,
633
+ });
634
+ expect(erc20VariableIncentive._config).toEqual(defaultOptions.config);
635
+ expect(erc20VariableIncentive._account).toEqual(defaultOptions.account);
636
+
637
+ // const erc1155Incentive = core.ERC1155Incentive({
638
+ // asset: zeroAddress,
639
+ // strategy: 0,
640
+ // tokenId: 1n,
641
+ // limit: 0n,
642
+ // extraData: '0x',
643
+ // });
644
+ // expect(erc1155Incentive._config).toEqual(defaultOptions.config);
645
+ // expect(erc1155Incentive._account).toEqual(defaultOptions.account);
646
+
647
+ const pointsIncentive = core.PointsIncentive({
648
+ venue: zeroAddress,
649
+ selector: '0x',
650
+ reward: 0n,
651
+ limit: 0n,
652
+ });
653
+ expect(pointsIncentive._config).toEqual(defaultOptions.config);
654
+ expect(pointsIncentive._account).toEqual(defaultOptions.account);
655
+
656
+ const signerValidator = core.SignerValidator(zeroAddress);
657
+ expect(signerValidator._config).toEqual(defaultOptions.config);
658
+ expect(signerValidator._account).toEqual(defaultOptions.account);
659
+ });
660
+
661
+ test('can subscribe to contract events', async () => {
662
+ const subscription = vi.fn();
663
+
664
+ const { core } = fixtures;
665
+ core.subscribe(subscription, { pollingInterval: 100 });
666
+ const { budget, erc20 } = budgets;
667
+ await core.createBoost({
668
+ protocolFee: 1n,
669
+ referralFee: 2n,
670
+ maxParticipants: 100n,
671
+ budget: budget,
672
+ action: core.EventAction(
673
+ makeMockEventActionPayload(
674
+ core.assertValidAddress(),
675
+ erc20.assertValidAddress(),
676
+ ),
677
+ ),
678
+ validator: core.SignerValidator({
679
+ signers: [defaultOptions.account.address],
680
+ validatorCaller: defaultOptions.account.address,
681
+ }),
682
+ allowList: core.SimpleAllowList({
683
+ owner: defaultOptions.account.address,
684
+ allowed: [defaultOptions.account.address],
685
+ }),
686
+ incentives: [
687
+ core.ERC20Incentive({
688
+ asset: erc20.assertValidAddress(),
689
+ reward: parseEther('1'),
690
+ limit: 100n,
691
+ strategy: StrategyType.POOL,
692
+ }),
693
+ ],
694
+ });
695
+
696
+ await new Promise((resolve) => {
697
+ setTimeout(resolve, 500);
698
+ });
699
+
700
+ expect(subscription).toHaveBeenCalledTimes(1);
701
+ });
702
+
703
+ test('can set a passthrough auth scheme', async () => {
704
+ const { core } = fixtures;
705
+
706
+ const auth = core.PassthroughAuth();
707
+ await auth.deploy();
708
+ await core.setCreateBoostAuth(auth);
709
+ expect((await core.createBoostAuth()).toLowerCase()).toBe(
710
+ auth.assertValidAddress(),
711
+ );
712
+ expect(await core.isAuthorized(zeroAddress)).toBe(true);
713
+ });
714
+
715
+ test('uses the provided validator when one is specified', async () => {
716
+ const { core } = fixtures;
717
+ const { budget, erc20 } = budgets;
718
+ const customValidator = core.SignerValidator({
719
+ signers: [budget.assertValidAddress()],
720
+ validatorCaller: core.assertValidAddress(),
721
+ });
722
+ const boost = await core.createBoost({
723
+ maxParticipants: 100n,
724
+ budget: budget,
725
+ action: core.EventAction(
726
+ makeMockEventActionPayload(
727
+ core.assertValidAddress(),
728
+ erc20.assertValidAddress(),
729
+ ),
730
+ ),
731
+ validator: customValidator,
732
+ allowList: core.SimpleAllowList({
733
+ owner: defaultOptions.account.address,
734
+ allowed: [defaultOptions.account.address],
735
+ }),
736
+ incentives: [
737
+ core.ERC20Incentive({
738
+ asset: erc20.assertValidAddress(),
739
+ reward: parseEther('1'),
740
+ limit: 100n,
741
+ strategy: StrategyType.POOL,
742
+ }),
743
+ ],
744
+ });
745
+
746
+ expect(boost.validator).toBe(customValidator);
747
+ const signers = await boost.validator.signers(budget.assertValidAddress());
748
+ expect(signers).toBe(true);
749
+ });
750
+
751
+ test('creates a boost with a default validator when none is provided', async () => {
752
+ const { core } = fixtures;
753
+ const { budget, erc20 } = budgets;
754
+ const boost = await core.createBoost({
755
+ maxParticipants: 100n,
756
+ budget: budget,
757
+ action: core.EventAction(
758
+ makeMockEventActionPayload(
759
+ core.assertValidAddress(),
760
+ erc20.assertValidAddress(),
761
+ ),
762
+ ),
763
+ allowList: core.OpenAllowList(),
764
+ incentives: [
765
+ core.ERC20Incentive({
766
+ asset: erc20.assertValidAddress(),
767
+ reward: parseEther('1'),
768
+ limit: 100n,
769
+ strategy: StrategyType.POOL,
770
+ }),
771
+ ],
772
+ });
773
+
774
+ const validator = boost.validator;
775
+
776
+ // expect boostCore to be a validatorCaller
777
+ expect(validator.payload?.validatorCaller).toBe(core.assertValidAddress());
778
+
779
+ // expect current account to be a signer
780
+ const signer = await validator.signers(defaultOptions.account.address);
781
+ expect(signer).toBeDefined();
782
+ expect(signer).toBe(true);
783
+ });
784
+
785
+ test('can retrieve the BoostClaimed event from a transaction hash', async () => {
786
+ // biome-ignore lint/style/noNonNullAssertion: we know this is defined
787
+ const referrer = accounts.at(1)!.account!,
788
+ // biome-ignore lint/style/noNonNullAssertion: we know this is defined
789
+ trustedSigner = accounts.at(0)!;
790
+ const erc20Incentive = fixtures.core.ERC20Incentive({
791
+ asset: budgets.erc20.assertValidAddress(),
792
+ strategy: StrategyType.POOL,
793
+ reward: 1n,
794
+ limit: 1n,
795
+ });
796
+ const boost = await freshBoost(fixtures, {
797
+ budget: budgets.budget,
798
+ incentives: [erc20Incentive],
799
+ });
800
+
801
+ const claimant = trustedSigner.account;
802
+ const incentiveData = pad('0xdef456232173821931823712381232131391321934');
803
+ const incentiveQuantity = 1;
804
+ const claimDataPayload = await boost.validator.encodeClaimData({
805
+ signer: trustedSigner,
806
+ incentiveData,
807
+ chainId: defaultOptions.config.chains[0].id,
808
+ incentiveQuantity,
809
+ claimant,
810
+ boostId: boost.id,
811
+ });
812
+
813
+ const {hash} = await fixtures.core.claimIncentiveRaw(
814
+ boost.id,
815
+ 0n,
816
+ referrer,
817
+ claimDataPayload,
818
+ { value: BOOST_CORE_CLAIM_FEE },
819
+ );
820
+
821
+ const claimInfo = await fixtures.core.getClaimFromTransaction({ hash })
822
+ expect(claimInfo).toBeDefined()
823
+ expect(claimInfo?.claimant).toBe(claimant)
824
+ expect(typeof claimInfo?.boostId).toBe('bigint')
825
+ expect(claimInfo?.referrer).toBe(referrer)
826
+ });
827
+ });