@boostxyz/sdk 0.0.0-alpha.10

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 (242) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +7 -0
  3. package/dist/Actions/Action.cjs +2 -0
  4. package/dist/Actions/Action.cjs.map +1 -0
  5. package/dist/Actions/Action.d.ts +31 -0
  6. package/dist/Actions/Action.d.ts.map +1 -0
  7. package/dist/Actions/Action.js +29 -0
  8. package/dist/Actions/Action.js.map +1 -0
  9. package/dist/Actions/ContractAction.d.ts +370 -0
  10. package/dist/Actions/ContractAction.d.ts.map +1 -0
  11. package/dist/Actions/ERC721MintAction.d.ts +513 -0
  12. package/dist/Actions/ERC721MintAction.d.ts.map +1 -0
  13. package/dist/Actions/EventAction.cjs +2 -0
  14. package/dist/Actions/EventAction.cjs.map +1 -0
  15. package/dist/Actions/EventAction.d.ts +694 -0
  16. package/dist/Actions/EventAction.d.ts.map +1 -0
  17. package/dist/Actions/EventAction.js +491 -0
  18. package/dist/Actions/EventAction.js.map +1 -0
  19. package/dist/AllowLists/AllowList.cjs +2 -0
  20. package/dist/AllowLists/AllowList.cjs.map +1 -0
  21. package/dist/AllowLists/AllowList.d.ts +32 -0
  22. package/dist/AllowLists/AllowList.d.ts.map +1 -0
  23. package/dist/AllowLists/AllowList.js +30 -0
  24. package/dist/AllowLists/AllowList.js.map +1 -0
  25. package/dist/AllowLists/SimpleAllowList.cjs +2 -0
  26. package/dist/AllowLists/SimpleAllowList.cjs.map +1 -0
  27. package/dist/AllowLists/SimpleAllowList.d.ts +481 -0
  28. package/dist/AllowLists/SimpleAllowList.d.ts.map +1 -0
  29. package/dist/AllowLists/SimpleAllowList.js +154 -0
  30. package/dist/AllowLists/SimpleAllowList.js.map +1 -0
  31. package/dist/AllowLists/SimpleDenyList.cjs +2 -0
  32. package/dist/AllowLists/SimpleDenyList.cjs.map +1 -0
  33. package/dist/AllowLists/SimpleDenyList.d.ts +335 -0
  34. package/dist/AllowLists/SimpleDenyList.d.ts.map +1 -0
  35. package/dist/AllowLists/SimpleDenyList.js +115 -0
  36. package/dist/AllowLists/SimpleDenyList.js.map +1 -0
  37. package/dist/Auth/Auth.cjs +2 -0
  38. package/dist/Auth/Auth.cjs.map +1 -0
  39. package/dist/Auth/Auth.d.ts +10 -0
  40. package/dist/Auth/Auth.d.ts.map +1 -0
  41. package/dist/Auth/Auth.js +5 -0
  42. package/dist/Auth/Auth.js.map +1 -0
  43. package/dist/Auth/PassthroughAuth.cjs +2 -0
  44. package/dist/Auth/PassthroughAuth.cjs.map +1 -0
  45. package/dist/Auth/PassthroughAuth.d.ts +51 -0
  46. package/dist/Auth/PassthroughAuth.d.ts.map +1 -0
  47. package/dist/Auth/PassthroughAuth.js +39 -0
  48. package/dist/Auth/PassthroughAuth.js.map +1 -0
  49. package/dist/Boost.cjs +2 -0
  50. package/dist/Boost.cjs.map +1 -0
  51. package/dist/Boost.d.ts +234 -0
  52. package/dist/Boost.d.ts.map +1 -0
  53. package/dist/Boost.js +162 -0
  54. package/dist/Boost.js.map +1 -0
  55. package/dist/BoostCore.cjs +3 -0
  56. package/dist/BoostCore.cjs.map +1 -0
  57. package/dist/BoostCore.d.ts +498 -0
  58. package/dist/BoostCore.d.ts.map +1 -0
  59. package/dist/BoostCore.js +1153 -0
  60. package/dist/BoostCore.js.map +1 -0
  61. package/dist/BoostRegistry.cjs +2 -0
  62. package/dist/BoostRegistry.cjs.map +1 -0
  63. package/dist/BoostRegistry.d.ts +243 -0
  64. package/dist/BoostRegistry.d.ts.map +1 -0
  65. package/dist/BoostRegistry.js +262 -0
  66. package/dist/BoostRegistry.js.map +1 -0
  67. package/dist/Budgets/Budget.cjs +2 -0
  68. package/dist/Budgets/Budget.cjs.map +1 -0
  69. package/dist/Budgets/Budget.d.ts +31 -0
  70. package/dist/Budgets/Budget.d.ts.map +1 -0
  71. package/dist/Budgets/Budget.js +29 -0
  72. package/dist/Budgets/Budget.js.map +1 -0
  73. package/dist/Budgets/ManagedBudget.cjs +2 -0
  74. package/dist/Budgets/ManagedBudget.cjs.map +1 -0
  75. package/dist/Budgets/ManagedBudget.d.ts +1103 -0
  76. package/dist/Budgets/ManagedBudget.d.ts.map +1 -0
  77. package/dist/Budgets/ManagedBudget.js +516 -0
  78. package/dist/Budgets/ManagedBudget.js.map +1 -0
  79. package/dist/Budgets/SimpleBudget.d.ts +824 -0
  80. package/dist/Budgets/SimpleBudget.d.ts.map +1 -0
  81. package/dist/Budgets/VestingBudget.d.ts +778 -0
  82. package/dist/Budgets/VestingBudget.d.ts.map +1 -0
  83. package/dist/Deployable/Contract.cjs +2 -0
  84. package/dist/Deployable/Contract.cjs.map +1 -0
  85. package/dist/Deployable/Contract.d.ts +125 -0
  86. package/dist/Deployable/Contract.d.ts.map +1 -0
  87. package/dist/Deployable/Contract.js +150 -0
  88. package/dist/Deployable/Contract.js.map +1 -0
  89. package/dist/Deployable/Deployable.cjs +2 -0
  90. package/dist/Deployable/Deployable.cjs.map +1 -0
  91. package/dist/Deployable/Deployable.d.ts +161 -0
  92. package/dist/Deployable/Deployable.d.ts.map +1 -0
  93. package/dist/Deployable/Deployable.js +131 -0
  94. package/dist/Deployable/Deployable.js.map +1 -0
  95. package/dist/Deployable/DeployableTarget.cjs +2 -0
  96. package/dist/Deployable/DeployableTarget.cjs.map +1 -0
  97. package/dist/Deployable/DeployableTarget.d.ts +116 -0
  98. package/dist/Deployable/DeployableTarget.d.ts.map +1 -0
  99. package/dist/Deployable/DeployableTarget.js +132 -0
  100. package/dist/Deployable/DeployableTarget.js.map +1 -0
  101. package/dist/Incentives/AllowListIncentive.cjs +2 -0
  102. package/dist/Incentives/AllowListIncentive.cjs.map +1 -0
  103. package/dist/Incentives/AllowListIncentive.d.ts +513 -0
  104. package/dist/Incentives/AllowListIncentive.d.ts.map +1 -0
  105. package/dist/Incentives/AllowListIncentive.js +201 -0
  106. package/dist/Incentives/AllowListIncentive.js.map +1 -0
  107. package/dist/Incentives/CGDAIncentive.cjs +2 -0
  108. package/dist/Incentives/CGDAIncentive.cjs.map +1 -0
  109. package/dist/Incentives/CGDAIncentive.d.ts +644 -0
  110. package/dist/Incentives/CGDAIncentive.d.ts.map +1 -0
  111. package/dist/Incentives/CGDAIncentive.js +271 -0
  112. package/dist/Incentives/CGDAIncentive.js.map +1 -0
  113. package/dist/Incentives/ERC1155Incentive.d.ts +713 -0
  114. package/dist/Incentives/ERC1155Incentive.d.ts.map +1 -0
  115. package/dist/Incentives/ERC20Incentive.cjs +2 -0
  116. package/dist/Incentives/ERC20Incentive.cjs.map +1 -0
  117. package/dist/Incentives/ERC20Incentive.d.ts +666 -0
  118. package/dist/Incentives/ERC20Incentive.d.ts.map +1 -0
  119. package/dist/Incentives/ERC20Incentive.js +312 -0
  120. package/dist/Incentives/ERC20Incentive.js.map +1 -0
  121. package/dist/Incentives/ERC20VariableIncentive.d.ts +582 -0
  122. package/dist/Incentives/ERC20VariableIncentive.d.ts.map +1 -0
  123. package/dist/Incentives/Incentive.cjs +2 -0
  124. package/dist/Incentives/Incentive.cjs.map +1 -0
  125. package/dist/Incentives/Incentive.d.ts +36 -0
  126. package/dist/Incentives/Incentive.d.ts.map +1 -0
  127. package/dist/Incentives/Incentive.js +299 -0
  128. package/dist/Incentives/Incentive.js.map +1 -0
  129. package/dist/Incentives/PointsIncentive.cjs +2 -0
  130. package/dist/Incentives/PointsIncentive.cjs.map +1 -0
  131. package/dist/Incentives/PointsIncentive.d.ts +659 -0
  132. package/dist/Incentives/PointsIncentive.d.ts.map +1 -0
  133. package/dist/Incentives/PointsIncentive.js +215 -0
  134. package/dist/Incentives/PointsIncentive.js.map +1 -0
  135. package/dist/Validators/SignerValidator.cjs +2 -0
  136. package/dist/Validators/SignerValidator.cjs.map +1 -0
  137. package/dist/Validators/SignerValidator.d.ts +745 -0
  138. package/dist/Validators/SignerValidator.d.ts.map +1 -0
  139. package/dist/Validators/SignerValidator.js +293 -0
  140. package/dist/Validators/SignerValidator.js.map +1 -0
  141. package/dist/Validators/Validator.cjs +2 -0
  142. package/dist/Validators/Validator.cjs.map +1 -0
  143. package/dist/Validators/Validator.d.ts +31 -0
  144. package/dist/Validators/Validator.d.ts.map +1 -0
  145. package/dist/Validators/Validator.js +27 -0
  146. package/dist/Validators/Validator.js.map +1 -0
  147. package/dist/claiming.cjs +2 -0
  148. package/dist/claiming.cjs.map +1 -0
  149. package/dist/claiming.d.ts +43 -0
  150. package/dist/claiming.d.ts.map +1 -0
  151. package/dist/claiming.js +17 -0
  152. package/dist/claiming.js.map +1 -0
  153. package/dist/componentInterfaces-CKCBwG16.cjs +2 -0
  154. package/dist/componentInterfaces-CKCBwG16.cjs.map +1 -0
  155. package/dist/componentInterfaces-DYkaxBda.js +13 -0
  156. package/dist/componentInterfaces-DYkaxBda.js.map +1 -0
  157. package/dist/errors.cjs +2 -0
  158. package/dist/errors.cjs.map +1 -0
  159. package/dist/errors.d.ts +441 -0
  160. package/dist/errors.d.ts.map +1 -0
  161. package/dist/errors.js +262 -0
  162. package/dist/errors.js.map +1 -0
  163. package/dist/generated-BDeDiaCK.js +4625 -0
  164. package/dist/generated-BDeDiaCK.js.map +1 -0
  165. package/dist/generated-wKBNvm48.cjs +3 -0
  166. package/dist/generated-wKBNvm48.cjs.map +1 -0
  167. package/dist/index.cjs +2 -0
  168. package/dist/index.cjs.map +1 -0
  169. package/dist/index.d.ts +25 -0
  170. package/dist/index.d.ts.map +1 -0
  171. package/dist/index.js +113 -0
  172. package/dist/index.js.map +1 -0
  173. package/dist/transfers.cjs +2 -0
  174. package/dist/transfers.cjs.map +1 -0
  175. package/dist/transfers.d.ts +198 -0
  176. package/dist/transfers.d.ts.map +1 -0
  177. package/dist/transfers.js +84 -0
  178. package/dist/transfers.js.map +1 -0
  179. package/dist/utils.cjs +2 -0
  180. package/dist/utils.cjs.map +1 -0
  181. package/dist/utils.d.ts +116 -0
  182. package/dist/utils.d.ts.map +1 -0
  183. package/dist/utils.js +30 -0
  184. package/dist/utils.js.map +1 -0
  185. package/package.json +211 -0
  186. package/src/Actions/Action.test.ts +75 -0
  187. package/src/Actions/Action.ts +61 -0
  188. package/src/Actions/ContractAction.test.ts +197 -0
  189. package/src/Actions/ContractAction.ts +301 -0
  190. package/src/Actions/ERC721MintAction.test.ts +112 -0
  191. package/src/Actions/ERC721MintAction.ts +292 -0
  192. package/src/Actions/EventAction.test.ts +205 -0
  193. package/src/Actions/EventAction.ts +811 -0
  194. package/src/AllowLists/AllowList.test.ts +64 -0
  195. package/src/AllowLists/AllowList.ts +60 -0
  196. package/src/AllowLists/SimpleAllowList.test.ts +52 -0
  197. package/src/AllowLists/SimpleAllowList.ts +284 -0
  198. package/src/AllowLists/SimpleDenyList.test.ts +52 -0
  199. package/src/AllowLists/SimpleDenyList.ts +227 -0
  200. package/src/Auth/Auth.ts +11 -0
  201. package/src/Auth/PassthroughAuth.test.ts +12 -0
  202. package/src/Auth/PassthroughAuth.ts +80 -0
  203. package/src/Boost.ts +290 -0
  204. package/src/BoostCore.test.ts +773 -0
  205. package/src/BoostCore.ts +1261 -0
  206. package/src/BoostRegistry.ts +467 -0
  207. package/src/Budgets/Budget.test.ts +27 -0
  208. package/src/Budgets/Budget.ts +61 -0
  209. package/src/Budgets/ManagedBudget.test.ts +154 -0
  210. package/src/Budgets/ManagedBudget.ts +796 -0
  211. package/src/Budgets/SimpleBudget.test.ts +152 -0
  212. package/src/Budgets/SimpleBudget.ts +564 -0
  213. package/src/Budgets/VestingBudget.test.ts +123 -0
  214. package/src/Budgets/VestingBudget.ts +602 -0
  215. package/src/Deployable/Contract.ts +229 -0
  216. package/src/Deployable/Deployable.ts +250 -0
  217. package/src/Deployable/DeployableTarget.ts +223 -0
  218. package/src/Incentives/AllowListIncentive.test.ts +143 -0
  219. package/src/Incentives/AllowListIncentive.ts +334 -0
  220. package/src/Incentives/CGDAIncentive.test.ts +132 -0
  221. package/src/Incentives/CGDAIncentive.ts +468 -0
  222. package/src/Incentives/ERC1155Incentive.test.ts +87 -0
  223. package/src/Incentives/ERC1155Incentive.ts +466 -0
  224. package/src/Incentives/ERC20Incentive.test.ts +130 -0
  225. package/src/Incentives/ERC20Incentive.ts +482 -0
  226. package/src/Incentives/ERC20VariableIncentive.test.ts +136 -0
  227. package/src/Incentives/ERC20VariableIncentive.ts +420 -0
  228. package/src/Incentives/Incentive.test.ts +92 -0
  229. package/src/Incentives/Incentive.ts +85 -0
  230. package/src/Incentives/PointsIncentive.test.ts +139 -0
  231. package/src/Incentives/PointsIncentive.ts +365 -0
  232. package/src/Validators/SignerValidator.test.ts +159 -0
  233. package/src/Validators/SignerValidator.ts +681 -0
  234. package/src/Validators/Validator.test.ts +21 -0
  235. package/src/Validators/Validator.ts +55 -0
  236. package/src/claiming.ts +56 -0
  237. package/src/errors.ts +542 -0
  238. package/src/index.test.ts +40 -0
  239. package/src/index.ts +53 -0
  240. package/src/transfers.ts +284 -0
  241. package/src/utils.test.ts +44 -0
  242. package/src/utils.ts +198 -0
@@ -0,0 +1,143 @@
1
+ import { loadFixture } from '@nomicfoundation/hardhat-network-helpers';
2
+ import { isAddress, pad, parseEther, zeroAddress } from 'viem';
3
+ import { beforeAll, describe, expect, test } from 'vitest';
4
+ import { accounts } from '../../test/accounts';
5
+ import {
6
+ type Fixtures,
7
+ defaultOptions,
8
+ deployFixtures,
9
+ freshBoost,
10
+ } from '../../test/helpers';
11
+ import { LIST_MANAGER_ROLE } from '../AllowLists/SimpleAllowList';
12
+ import { PointsIncentive } from './PointsIncentive';
13
+
14
+ let fixtures: Fixtures;
15
+
16
+ function freshAllowList(fixtures: Fixtures) {
17
+ return function freshAllowList() {
18
+ return fixtures.registry.clone(
19
+ crypto.randomUUID(),
20
+ fixtures.core.SimpleAllowList({
21
+ owner: defaultOptions.account.address,
22
+ allowed: [],
23
+ }),
24
+ );
25
+ };
26
+ }
27
+
28
+ describe('AllowListIncentive', () => {
29
+ beforeAll(async () => {
30
+ fixtures = await loadFixture(deployFixtures);
31
+ });
32
+
33
+ test('can successfully be deployed', async () => {
34
+ const action = new PointsIncentive(defaultOptions, {
35
+ venue: zeroAddress,
36
+ selector: '0xdeadb33f',
37
+ reward: 1n,
38
+ limit: 1n,
39
+ });
40
+ await action.deploy();
41
+ expect(isAddress(action.assertValidAddress())).toBe(true);
42
+ });
43
+
44
+ test('can claim', async () => {
45
+ // biome-ignore lint/style/noNonNullAssertion: we know this is defined
46
+ const referrer = accounts.at(1)?.account!;
47
+ // biome-ignore lint/style/noNonNullAssertion: we know this is defined
48
+ const trustedSigner = accounts.at(0)!;
49
+ const allowList = await loadFixture(freshAllowList(fixtures));
50
+ const allowListIncentive = new fixtures.bases.AllowListIncentive(
51
+ defaultOptions,
52
+ {
53
+ allowList: allowList.assertValidAddress(),
54
+ limit: 3n,
55
+ },
56
+ );
57
+ const boost = await freshBoost(fixtures, {
58
+ incentives: [allowListIncentive],
59
+ });
60
+ await allowList.grantRoles(
61
+ allowListIncentive.assertValidAddress(),
62
+ LIST_MANAGER_ROLE,
63
+ );
64
+
65
+ const claimant = trustedSigner.account;
66
+ const incentiveData = pad('0xdef456232173821931823712381232131391321934');
67
+ console.log(claimant);
68
+
69
+ const incentiveQuantity = 1;
70
+ const claimDataPayload = await boost.validator.encodeClaimData({
71
+ signer: trustedSigner,
72
+ incentiveData,
73
+ chainId: defaultOptions.config.chains[0].id,
74
+ incentiveQuantity,
75
+ claimant,
76
+ boostId: boost.id,
77
+ });
78
+
79
+ //await boost.validator.setValidatorCaller(boost.assertValidAddress());
80
+ await fixtures.core.claimIncentive(
81
+ boost.id,
82
+ 0n,
83
+ referrer,
84
+ claimDataPayload,
85
+ { value: parseEther('0.000075'), account: trustedSigner.privateKey },
86
+ );
87
+ expect(await allowList.isAllowed(trustedSigner.account)).toBe(true);
88
+ });
89
+
90
+ test('cannot claim twice', async () => {
91
+ // biome-ignore lint/style/noNonNullAssertion: we know this is defined
92
+ const referrer = accounts.at(1)?.account!;
93
+ // biome-ignore lint/style/noNonNullAssertion: we know this is defined
94
+ const trustedSigner = accounts.at(0)!;
95
+ const allowList = await loadFixture(freshAllowList(fixtures));
96
+ const allowListIncentive = new fixtures.bases.AllowListIncentive(
97
+ defaultOptions,
98
+ {
99
+ allowList: allowList.assertValidAddress(),
100
+ limit: 3n,
101
+ },
102
+ );
103
+ const boost = await freshBoost(fixtures, {
104
+ incentives: [allowListIncentive],
105
+ });
106
+ await allowList.grantRoles(
107
+ allowListIncentive.assertValidAddress(),
108
+ LIST_MANAGER_ROLE,
109
+ );
110
+ const incentiveQuantity = 1;
111
+ const claimant = trustedSigner.account;
112
+ const incentiveData = pad('0xdef456232173821931823712381232131391321934');
113
+ console.log(claimant);
114
+
115
+ const claimDataPayload = await boost.validator.encodeClaimData({
116
+ signer: trustedSigner,
117
+ incentiveData,
118
+ chainId: defaultOptions.config.chains[0].id,
119
+ incentiveQuantity,
120
+ claimant,
121
+ boostId: boost.id,
122
+ });
123
+
124
+ await fixtures.core.claimIncentive(
125
+ boost.id,
126
+ 0n,
127
+ referrer,
128
+ claimDataPayload,
129
+ { value: parseEther('0.000075'), account: trustedSigner.privateKey },
130
+ );
131
+ try {
132
+ await fixtures.core.claimIncentive(
133
+ boost.id,
134
+ 0n,
135
+ referrer,
136
+ claimDataPayload,
137
+ { value: parseEther('0.000075'), account: trustedSigner.privateKey },
138
+ );
139
+ } catch (e) {
140
+ expect(e).toBeInstanceOf(Error);
141
+ }
142
+ });
143
+ });
@@ -0,0 +1,334 @@
1
+ import {
2
+ allowListIncentiveAbi,
3
+ readAllowListIncentiveAllowList,
4
+ readAllowListIncentiveClaimed,
5
+ readAllowListIncentiveClaims,
6
+ readAllowListIncentiveIsClaimable,
7
+ readAllowListIncentiveLimit,
8
+ readAllowListIncentiveOwner,
9
+ readAllowListIncentiveReward,
10
+ simulateAllowListIncentiveClaim,
11
+ writeAllowListIncentiveClaim,
12
+ } from '@boostxyz/evm';
13
+ import { bytecode } from '@boostxyz/evm/artifacts/contracts/incentives/AllowListIncentive.sol/AllowListIncentive.json';
14
+ import {
15
+ type Address,
16
+ type ContractEventName,
17
+ type Hex,
18
+ encodeAbiParameters,
19
+ } from 'viem';
20
+ import { SimpleAllowList } from '../AllowLists/AllowList';
21
+ import type {
22
+ DeployableOptions,
23
+ GenericDeployableParams,
24
+ } from '../Deployable/Deployable';
25
+ import { DeployableTarget } from '../Deployable/DeployableTarget';
26
+ import { type ClaimPayload, prepareClaimPayload } from '../claiming';
27
+ import {
28
+ type GenericLog,
29
+ type ReadParams,
30
+ RegistryType,
31
+ type WriteParams,
32
+ } from '../utils';
33
+
34
+ export { allowListIncentiveAbi };
35
+
36
+ /**
37
+ * The object representation of a `AllowListIncentive.InitPayload`
38
+ *
39
+ * @export
40
+ * @interface AllowListIncentivePayload
41
+ * @typedef {AllowListIncentivePayload}
42
+ */
43
+ export interface AllowListIncentivePayload {
44
+ /**
45
+ * The address to the allowlist to add claimers to.
46
+ *
47
+ * @type {Address}
48
+ */
49
+ allowList: Address;
50
+ /**
51
+ * The maximum number of claims that can be made (one per address)
52
+ *
53
+ * @type {bigint}
54
+ */
55
+ limit: bigint;
56
+ }
57
+
58
+ /**
59
+ * A generic `viem.Log` event with support for `AllowListIncentive` event types.
60
+ *
61
+ * @export
62
+ * @typedef {AllowListIncentiveLog}
63
+ * @template {ContractEventName<
64
+ * typeof allowListIncentiveAbi
65
+ * >} [event=ContractEventName<typeof allowListIncentiveAbi>]
66
+ */
67
+ export type AllowListIncentiveLog<
68
+ event extends ContractEventName<
69
+ typeof allowListIncentiveAbi
70
+ > = ContractEventName<typeof allowListIncentiveAbi>,
71
+ > = GenericLog<typeof allowListIncentiveAbi, event>;
72
+
73
+ /**
74
+ * An incentive implementation that grants the claimer a slot on an {SimpleAllowList}
75
+ * In order for any claim to be successful:
76
+ * - The claimer must not already be on the allow list; and
77
+ * - The maximum number of claims must not have been reached; and
78
+ * - This contract must be authorized to modify the allow list
79
+ *
80
+ * @export
81
+ * @class AllowListIncentive
82
+ * @typedef {AllowListIncentive}
83
+ * @extends {DeployableTarget<AllowListIncentivePayload>}
84
+ */
85
+ export class AllowListIncentive extends DeployableTarget<
86
+ AllowListIncentivePayload,
87
+ typeof allowListIncentiveAbi
88
+ > {
89
+ public override readonly abi = allowListIncentiveAbi;
90
+ /**
91
+ * @inheritdoc
92
+ *
93
+ * @public
94
+ * @static
95
+ * @type {Address}
96
+ */
97
+ public static override base: Address = import.meta.env
98
+ .VITE_ALLOWLIST_INCENTIVE_BASE;
99
+ /**
100
+ * @inheritdoc
101
+ *
102
+ * @public
103
+ * @static
104
+ * @type {RegistryType}
105
+ */
106
+ public static override registryType: RegistryType = RegistryType.INCENTIVE;
107
+
108
+ /**
109
+ * The owner of the allowList
110
+ *
111
+ * @public
112
+ * @async
113
+ * @param {?ReadParams<typeof allowListIncentiveAbi, 'owner'>} [params]
114
+ * @returns {unknown}
115
+ */
116
+ public async owner(
117
+ params?: ReadParams<typeof allowListIncentiveAbi, 'owner'>,
118
+ ) {
119
+ return await readAllowListIncentiveOwner(this._config, {
120
+ address: this.assertValidAddress(),
121
+ args: [],
122
+ // biome-ignore lint/suspicious/noExplicitAny: Accept any shape of valid wagmi/viem parameters, wagmi does the same thing internally
123
+ ...(params as any),
124
+ });
125
+ }
126
+
127
+ /**
128
+ * The number of claims that have been made
129
+ *
130
+ * @public
131
+ * @async
132
+ * @param {?ReadParams<typeof allowListIncentiveAbi, 'claims'>} [params]
133
+ * @returns {Promise<bigint>}
134
+ */
135
+ public async claims(
136
+ params?: ReadParams<typeof allowListIncentiveAbi, 'claims'>,
137
+ ) {
138
+ return await readAllowListIncentiveClaims(this._config, {
139
+ address: this.assertValidAddress(),
140
+ args: [],
141
+ // biome-ignore lint/suspicious/noExplicitAny: Accept any shape of valid wagmi/viem parameters, wagmi does the same thing internally
142
+ ...(params as any),
143
+ });
144
+ }
145
+
146
+ /**
147
+ * The reward amount issued for each claim
148
+ *
149
+ * @public
150
+ * @async
151
+ * @param {?ReadParams<typeof allowListIncentiveAbi, 'reward'>} [params]
152
+ * @returns {Promise<bigint>}
153
+ */
154
+ public async reward(
155
+ params?: ReadParams<typeof allowListIncentiveAbi, 'reward'>,
156
+ ) {
157
+ return await readAllowListIncentiveReward(this._config, {
158
+ address: this.assertValidAddress(),
159
+ args: [],
160
+ // biome-ignore lint/suspicious/noExplicitAny: Accept any shape of valid wagmi/viem parameters, wagmi does the same thing internally
161
+ ...(params as any),
162
+ });
163
+ }
164
+
165
+ /**
166
+ * Get the claim status for a user
167
+ *
168
+ * @public
169
+ * @async
170
+ * @param {Address} address
171
+ * @param {?ReadParams<typeof allowListIncentiveAbi, 'claimed'>} [params]
172
+ * @returns {Promise<boolean>}
173
+ */
174
+ public async claimed(
175
+ address: Address,
176
+ params?: ReadParams<typeof allowListIncentiveAbi, 'claimed'>,
177
+ ) {
178
+ return await readAllowListIncentiveClaimed(this._config, {
179
+ address: this.assertValidAddress(),
180
+ args: [address],
181
+ // biome-ignore lint/suspicious/noExplicitAny: Accept any shape of valid wagmi/viem parameters, wagmi does the same thing internally
182
+ ...(params as any),
183
+ });
184
+ }
185
+
186
+ /**
187
+ * The {@link SimpleAllowList} contract
188
+ *
189
+ * @public
190
+ * @async
191
+ * @param {?ReadParams<typeof allowListIncentiveAbi, 'allowList'>} [params]
192
+ * @returns {Promise<SimpleAllowList>}
193
+ */
194
+ public async allowList(
195
+ params?: ReadParams<typeof allowListIncentiveAbi, 'allowList'>,
196
+ ): Promise<SimpleAllowList> {
197
+ const address = await readAllowListIncentiveAllowList(this._config, {
198
+ address: this.assertValidAddress(),
199
+ // biome-ignore lint/suspicious/noExplicitAny: Accept any shape of valid wagmi/viem parameters, wagmi does the same thing internally
200
+ ...(params as any),
201
+ });
202
+ return new SimpleAllowList(
203
+ { config: this._config, account: this._account },
204
+ address,
205
+ );
206
+ }
207
+
208
+ /**
209
+ * The maximum number of claims that can be made (one per address)
210
+ *
211
+ * @public
212
+ * @async
213
+ * @param {?ReadParams<typeof allowListIncentiveAbi, 'limit'>} [params]
214
+ * @returns {unknown}
215
+ */
216
+ public async limit(
217
+ params?: ReadParams<typeof allowListIncentiveAbi, 'limit'>,
218
+ ) {
219
+ return await readAllowListIncentiveLimit(this._config, {
220
+ address: this.assertValidAddress(),
221
+ // biome-ignore lint/suspicious/noExplicitAny: Accept any shape of valid wagmi/viem parameters, wagmi does the same thing internally
222
+ ...(params as any),
223
+ });
224
+ }
225
+
226
+ /**
227
+ * Claim a slot on the {@link SimpleAllowList}
228
+ *
229
+ * @public
230
+ * @async
231
+ * @param {Pick<ClaimPayload, 'target'>} payload
232
+ * @param {?WriteParams<typeof allowListIncentiveAbi, 'claim'>} [params]
233
+ * @returns {Promise<true>} - return true if successful, otherwise revert
234
+ */
235
+ protected async claim(
236
+ payload: Pick<ClaimPayload, 'target'>,
237
+ params?: WriteParams<typeof allowListIncentiveAbi, 'claim'>,
238
+ ) {
239
+ return await this.awaitResult(this.claimRaw(payload, params));
240
+ }
241
+
242
+ /**
243
+ * Claim a slot on the {@link SimpleAllowList}
244
+ *
245
+ * @public
246
+ * @async
247
+ * @param {Pick<ClaimPayload, 'target'>} payload
248
+ * @param {?WriteParams<typeof allowListIncentiveAbi, 'claim'>} [params]
249
+ * @returns {Promise<true>} - return true if successful, otherwise revert
250
+ */
251
+ protected async claimRaw(
252
+ payload: Pick<ClaimPayload, 'target'>,
253
+ params?: WriteParams<typeof allowListIncentiveAbi, 'claim'>,
254
+ ) {
255
+ const { request, result } = await simulateAllowListIncentiveClaim(
256
+ this._config,
257
+ {
258
+ address: this.assertValidAddress(),
259
+ args: [prepareClaimPayload(payload)],
260
+ ...this.optionallyAttachAccount(),
261
+ // biome-ignore lint/suspicious/noExplicitAny: Accept any shape of valid wagmi/viem parameters, wagmi does the same thing internally
262
+ ...(params as any),
263
+ },
264
+ );
265
+ const hash = await writeAllowListIncentiveClaim(this._config, request);
266
+ return { hash, result };
267
+ }
268
+
269
+ /**
270
+ * Check if an incentive is claimable
271
+ *
272
+ * @public
273
+ * @async
274
+ * @param {Pick<ClaimPayload, 'target'>} payload
275
+ * @param {?ReadParams<typeof allowListIncentiveAbi, 'isClaimable'>} [params]
276
+ * @returns {Promise<boolean>} - True if the incentive is claimable based on the data payload
277
+ */
278
+ public async isClaimable(
279
+ payload: Pick<ClaimPayload, 'target'>,
280
+ params?: ReadParams<typeof allowListIncentiveAbi, 'isClaimable'>,
281
+ ) {
282
+ return await readAllowListIncentiveIsClaimable(this._config, {
283
+ address: this.assertValidAddress(),
284
+ args: [prepareClaimPayload(payload)],
285
+ // biome-ignore lint/suspicious/noExplicitAny: Accept any shape of valid wagmi/viem parameters, wagmi does the same thing internally
286
+ ...(params as any),
287
+ });
288
+ }
289
+
290
+ /**
291
+ * @inheritdoc
292
+ *
293
+ * @public
294
+ * @param {?AllowListIncentivePayload} [_payload]
295
+ * @param {?DeployableOptions} [_options]
296
+ * @returns {GenericDeployableParams}
297
+ */
298
+ public override buildParameters(
299
+ _payload?: AllowListIncentivePayload,
300
+ _options?: DeployableOptions,
301
+ ): GenericDeployableParams {
302
+ const [payload, options] = this.validateDeploymentConfig(
303
+ _payload,
304
+ _options,
305
+ );
306
+ return {
307
+ abi: allowListIncentiveAbi,
308
+ bytecode: bytecode as Hex,
309
+ args: [prepareAllowListIncentivePayload(payload)],
310
+ ...this.optionallyAttachAccount(options.account),
311
+ };
312
+ }
313
+ }
314
+
315
+ /**
316
+ * Given a {@link AllowListIncentivePayload}, properly encode a `AllowListIncentive.InitPayload` for use with {@link AllowListIncentive} initialization.
317
+ *
318
+ * @param {AllowListIncentivePayload} param0
319
+ * @param {Address} param0.allowList - The address to the allowlist to add claimers to.
320
+ * @param {bigint} param0.limit - The maximum number of claims that can be made (one per address)
321
+ * @returns {Hex}
322
+ */
323
+ export const prepareAllowListIncentivePayload = ({
324
+ allowList,
325
+ limit,
326
+ }: AllowListIncentivePayload) => {
327
+ return encodeAbiParameters(
328
+ [
329
+ { type: 'address', name: 'allowList' },
330
+ { type: 'uint256', name: 'limit' },
331
+ ],
332
+ [allowList, limit],
333
+ );
334
+ };
@@ -0,0 +1,132 @@
1
+ import { readMockErc20BalanceOf } from '@boostxyz/evm';
2
+ import { loadFixture } from '@nomicfoundation/hardhat-network-helpers';
3
+ import { isAddress, pad, parseEther } from 'viem';
4
+ import { beforeAll, beforeEach, describe, expect, test } from 'vitest';
5
+ import { accounts } from '../../test/accounts';
6
+ import {
7
+ type BudgetFixtures,
8
+ type Fixtures,
9
+ defaultOptions,
10
+ deployFixtures,
11
+ freshBoost,
12
+ fundBudget,
13
+ } from '../../test/helpers';
14
+ import { CGDAIncentive } from './CGDAIncentive';
15
+
16
+ let fixtures: Fixtures, budgets: BudgetFixtures;
17
+
18
+ describe('CGDAIncentive', () => {
19
+ beforeAll(async () => {
20
+ fixtures = await loadFixture(deployFixtures);
21
+ });
22
+
23
+ beforeEach(async () => {
24
+ budgets = await loadFixture(fundBudget(defaultOptions, fixtures));
25
+ });
26
+
27
+ test('can successfully be deployed', async () => {
28
+ const action = new CGDAIncentive(defaultOptions, {
29
+ asset: budgets.erc20.assertValidAddress(),
30
+ initialReward: 1n,
31
+ totalBudget: 10n,
32
+ rewardBoost: 1n,
33
+ rewardDecay: 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 erc20Incentive = fixtures.core.CGDAIncentive({
45
+ asset: budgets.erc20.assertValidAddress(),
46
+ initialReward: 1n,
47
+ totalBudget: 10n,
48
+ rewardBoost: 1n,
49
+ rewardDecay: 1n,
50
+ });
51
+ const boost = await freshBoost(fixtures, {
52
+ budget: budgets.budget,
53
+ incentives: [erc20Incentive],
54
+ });
55
+
56
+ const claimant = trustedSigner.account;
57
+ const incentiveData = pad('0xdef456232173821931823712381232131391321934');
58
+
59
+ const incentiveQuantity = 1;
60
+ const claimDataPayload = await boost.validator.encodeClaimData({
61
+ signer: trustedSigner,
62
+ incentiveData,
63
+ chainId: defaultOptions.config.chains[0].id,
64
+ incentiveQuantity,
65
+ claimant,
66
+ boostId: boost.id,
67
+ });
68
+
69
+ await fixtures.core.claimIncentive(
70
+ boost.id,
71
+ 0n,
72
+ referrer,
73
+ claimDataPayload,
74
+ { value: parseEther('0.000075') },
75
+ );
76
+ expect(
77
+ await readMockErc20BalanceOf(defaultOptions.config, {
78
+ address: budgets.erc20.assertValidAddress(),
79
+ args: [defaultOptions.account.address],
80
+ }),
81
+ ).toBe(1n);
82
+ });
83
+
84
+ test('cannot claim twice', async () => {
85
+ // biome-ignore lint/style/noNonNullAssertion: we know this is defined
86
+ const referrer = accounts.at(1)!.account!;
87
+ // biome-ignore lint/style/noNonNullAssertion: we know this is defined
88
+ const trustedSigner = accounts.at(0)!;
89
+ const erc20Incentive = fixtures.core.CGDAIncentive({
90
+ asset: budgets.erc20.assertValidAddress(),
91
+ initialReward: 1n,
92
+ totalBudget: 10n,
93
+ rewardBoost: 1n,
94
+ rewardDecay: 1n,
95
+ });
96
+ const boost = await freshBoost(fixtures, {
97
+ budget: budgets.budget,
98
+ incentives: [erc20Incentive],
99
+ });
100
+
101
+ const claimant = trustedSigner.account;
102
+ const incentiveData = pad('0xdef456232173821931823712381232131391321934');
103
+ const incentiveQuantity = 1;
104
+ const claimDataPayload = await boost.validator.encodeClaimData({
105
+ signer: trustedSigner,
106
+ incentiveData,
107
+ chainId: defaultOptions.config.chains[0].id,
108
+ incentiveQuantity,
109
+ claimant,
110
+ boostId: boost.id,
111
+ });
112
+
113
+ await fixtures.core.claimIncentive(
114
+ boost.id,
115
+ 0n,
116
+ referrer,
117
+ claimDataPayload,
118
+ { value: parseEther('0.000075') },
119
+ );
120
+ try {
121
+ await fixtures.core.claimIncentive(
122
+ boost.id,
123
+ 0n,
124
+ referrer,
125
+ claimDataPayload,
126
+ { value: parseEther('0.000075') },
127
+ );
128
+ } catch (e) {
129
+ expect(e).toBeInstanceOf(Error);
130
+ }
131
+ });
132
+ });