@boostxyz/sdk 0.0.0-alpha.17 → 0.0.0-alpha.19

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 (205) hide show
  1. package/dist/Actions/Action.cjs +1 -1
  2. package/dist/Actions/Action.cjs.map +1 -1
  3. package/dist/Actions/Action.js +13 -13
  4. package/dist/Actions/ContractAction.d.ts +9 -9
  5. package/dist/Actions/ContractAction.d.ts.map +1 -1
  6. package/dist/Actions/ERC721MintAction.d.ts +12 -12
  7. package/dist/Actions/ERC721MintAction.d.ts.map +1 -1
  8. package/dist/Actions/EventAction.cjs +1 -1
  9. package/dist/Actions/EventAction.cjs.map +1 -1
  10. package/dist/Actions/EventAction.d.ts +32 -49
  11. package/dist/Actions/EventAction.d.ts.map +1 -1
  12. package/dist/Actions/EventAction.js +13 -962
  13. package/dist/Actions/EventAction.js.map +1 -1
  14. package/dist/AllowLists/AllowList.cjs +1 -1
  15. package/dist/AllowLists/AllowList.js +3 -3
  16. package/dist/AllowLists/SimpleAllowList.cjs +1 -1
  17. package/dist/AllowLists/SimpleAllowList.cjs.map +1 -1
  18. package/dist/AllowLists/SimpleAllowList.d.ts +5 -5
  19. package/dist/AllowLists/SimpleAllowList.js +24 -24
  20. package/dist/AllowLists/SimpleAllowList.js.map +1 -1
  21. package/dist/AllowLists/SimpleDenyList.cjs +1 -1
  22. package/dist/AllowLists/SimpleDenyList.d.ts +6 -6
  23. package/dist/AllowLists/SimpleDenyList.js +3 -3
  24. package/dist/Auth/PassthroughAuth.cjs +1 -1
  25. package/dist/Auth/PassthroughAuth.js +1 -1
  26. package/dist/Boost.cjs.map +1 -1
  27. package/dist/Boost.d.ts +18 -0
  28. package/dist/Boost.d.ts.map +1 -1
  29. package/dist/Boost.js.map +1 -1
  30. package/dist/BoostCore-BiPwp6SR.cjs +3 -0
  31. package/dist/BoostCore-BiPwp6SR.cjs.map +1 -0
  32. package/dist/BoostCore-kwoUw7YE.js +1477 -0
  33. package/dist/BoostCore-kwoUw7YE.js.map +1 -0
  34. package/dist/BoostCore.cjs +1 -2
  35. package/dist/BoostCore.cjs.map +1 -1
  36. package/dist/BoostCore.d.ts +86 -36
  37. package/dist/BoostCore.d.ts.map +1 -1
  38. package/dist/BoostCore.js +29 -1273
  39. package/dist/BoostCore.js.map +1 -1
  40. package/dist/BoostRegistry.cjs +1 -1
  41. package/dist/BoostRegistry.cjs.map +1 -1
  42. package/dist/BoostRegistry.d.ts +25 -19
  43. package/dist/BoostRegistry.d.ts.map +1 -1
  44. package/dist/BoostRegistry.js +30 -29
  45. package/dist/BoostRegistry.js.map +1 -1
  46. package/dist/Budgets/Budget.cjs +1 -1
  47. package/dist/Budgets/Budget.js +2 -2
  48. package/dist/Budgets/ManagedBudget.cjs +1 -1
  49. package/dist/Budgets/ManagedBudget.cjs.map +1 -1
  50. package/dist/Budgets/ManagedBudget.d.ts +18 -18
  51. package/dist/Budgets/ManagedBudget.js +48 -48
  52. package/dist/Budgets/ManagedBudget.js.map +1 -1
  53. package/dist/Budgets/VestingBudget.d.ts +23 -23
  54. package/dist/Deployable/Contract.cjs +1 -1
  55. package/dist/Deployable/Contract.cjs.map +1 -1
  56. package/dist/Deployable/Contract.d.ts +4 -5
  57. package/dist/Deployable/Contract.d.ts.map +1 -1
  58. package/dist/Deployable/Contract.js +4 -5
  59. package/dist/Deployable/Contract.js.map +1 -1
  60. package/dist/Deployable/Deployable.cjs.map +1 -1
  61. package/dist/Deployable/Deployable.d.ts +1 -1
  62. package/dist/Deployable/Deployable.js +1 -1
  63. package/dist/Deployable/Deployable.js.map +1 -1
  64. package/dist/Deployable/DeployableTarget.cjs +1 -1
  65. package/dist/Deployable/DeployableTarget.cjs.map +1 -1
  66. package/dist/Deployable/DeployableTarget.d.ts +5 -5
  67. package/dist/Deployable/DeployableTarget.js +6 -6
  68. package/dist/Deployable/DeployableTarget.js.map +1 -1
  69. package/dist/Deployable/DeployableTargetWithRBAC.cjs +1 -1
  70. package/dist/Deployable/DeployableTargetWithRBAC.cjs.map +1 -1
  71. package/dist/Deployable/DeployableTargetWithRBAC.d.ts +15 -15
  72. package/dist/Deployable/DeployableTargetWithRBAC.js +33 -33
  73. package/dist/Deployable/DeployableTargetWithRBAC.js.map +1 -1
  74. package/dist/EventAction-D5tnm00s.js +1355 -0
  75. package/dist/EventAction-D5tnm00s.js.map +1 -0
  76. package/dist/EventAction-DBDRaG4A.cjs +2 -0
  77. package/dist/EventAction-DBDRaG4A.cjs.map +1 -0
  78. package/dist/{Incentive-DJf-vdyL.js → Incentive-Bp8Sez7M.js} +61 -62
  79. package/dist/Incentive-Bp8Sez7M.js.map +1 -0
  80. package/dist/{Incentive-DNwROd1r.cjs → Incentive-Djnzseoj.cjs} +2 -2
  81. package/dist/Incentive-Djnzseoj.cjs.map +1 -0
  82. package/dist/Incentives/AllowListIncentive.cjs +1 -1
  83. package/dist/Incentives/AllowListIncentive.cjs.map +1 -1
  84. package/dist/Incentives/AllowListIncentive.d.ts +12 -12
  85. package/dist/Incentives/AllowListIncentive.js +19 -19
  86. package/dist/Incentives/AllowListIncentive.js.map +1 -1
  87. package/dist/Incentives/CGDAIncentive.cjs +1 -1
  88. package/dist/Incentives/CGDAIncentive.cjs.map +1 -1
  89. package/dist/Incentives/CGDAIncentive.d.ts +15 -15
  90. package/dist/Incentives/CGDAIncentive.js +18 -18
  91. package/dist/Incentives/CGDAIncentive.js.map +1 -1
  92. package/dist/Incentives/ERC1155Incentive.d.ts +30 -30
  93. package/dist/Incentives/ERC20Incentive.cjs +1 -1
  94. package/dist/Incentives/ERC20Incentive.cjs.map +1 -1
  95. package/dist/Incentives/ERC20Incentive.d.ts +23 -23
  96. package/dist/Incentives/ERC20Incentive.js +25 -25
  97. package/dist/Incentives/ERC20Incentive.js.map +1 -1
  98. package/dist/Incentives/ERC20VariableCriteriaIncentive.d.ts +523 -0
  99. package/dist/Incentives/ERC20VariableCriteriaIncentive.d.ts.map +1 -0
  100. package/dist/Incentives/ERC20VariableIncentive.d.ts +19 -19
  101. package/dist/Incentives/Incentive.cjs +1 -1
  102. package/dist/Incentives/Incentive.d.ts +3 -3
  103. package/dist/Incentives/Incentive.d.ts.map +1 -1
  104. package/dist/Incentives/Incentive.js +3 -3
  105. package/dist/Incentives/PointsIncentive.cjs +1 -1
  106. package/dist/Incentives/PointsIncentive.cjs.map +1 -1
  107. package/dist/Incentives/PointsIncentive.d.ts +14 -14
  108. package/dist/Incentives/PointsIncentive.js +21 -21
  109. package/dist/Incentives/PointsIncentive.js.map +1 -1
  110. package/dist/{SimpleDenyList-DMlUkmAn.cjs → SimpleDenyList-BwfNjRsg.cjs} +2 -2
  111. package/dist/SimpleDenyList-BwfNjRsg.cjs.map +1 -0
  112. package/dist/{SimpleDenyList-DvUvmOeE.js → SimpleDenyList-Cn5WpNn0.js} +9 -9
  113. package/dist/SimpleDenyList-Cn5WpNn0.js.map +1 -0
  114. package/dist/Validators/SignerValidator.cjs +1 -1
  115. package/dist/Validators/SignerValidator.cjs.map +1 -1
  116. package/dist/Validators/SignerValidator.d.ts +14 -14
  117. package/dist/Validators/SignerValidator.js +19 -19
  118. package/dist/Validators/SignerValidator.js.map +1 -1
  119. package/dist/Validators/Validator.cjs +1 -1
  120. package/dist/Validators/Validator.cjs.map +1 -1
  121. package/dist/Validators/Validator.d.ts +1 -1
  122. package/dist/Validators/Validator.js +6 -6
  123. package/dist/Validators/Validator.js.map +1 -1
  124. package/dist/claiming.cjs.map +1 -1
  125. package/dist/claiming.d.ts +1 -1
  126. package/dist/claiming.js.map +1 -1
  127. package/dist/componentInterfaces-D09mhzxO.cjs +2 -0
  128. package/dist/componentInterfaces-D09mhzxO.cjs.map +1 -0
  129. package/dist/componentInterfaces-RXBMI5yH.js +14 -0
  130. package/dist/componentInterfaces-RXBMI5yH.js.map +1 -0
  131. package/dist/deployments-BM42vImE.js +43 -0
  132. package/dist/deployments-BM42vImE.js.map +1 -0
  133. package/dist/deployments-CMdF5uEC.cjs +2 -0
  134. package/dist/deployments-CMdF5uEC.cjs.map +1 -0
  135. package/dist/deployments.json +15 -12
  136. package/dist/errors.cjs +1 -1
  137. package/dist/errors.cjs.map +1 -1
  138. package/dist/errors.d.ts +132 -0
  139. package/dist/errors.d.ts.map +1 -1
  140. package/dist/errors.js +122 -36
  141. package/dist/errors.js.map +1 -1
  142. package/dist/generated-B0tk-c9b.cjs +3 -0
  143. package/dist/generated-B0tk-c9b.cjs.map +1 -0
  144. package/dist/{generated-C_7Jx3YG.js → generated-B7VaSah4.js} +631 -343
  145. package/dist/generated-B7VaSah4.js.map +1 -0
  146. package/dist/index.cjs +1 -1
  147. package/dist/index.d.ts +1 -0
  148. package/dist/index.d.ts.map +1 -1
  149. package/dist/index.js +135 -126
  150. package/dist/transfers.cjs.map +1 -1
  151. package/dist/transfers.d.ts +1 -1
  152. package/dist/transfers.js.map +1 -1
  153. package/dist/utils.cjs.map +1 -1
  154. package/dist/utils.d.ts +1 -1
  155. package/dist/utils.js.map +1 -1
  156. package/package.json +5 -5
  157. package/src/Actions/ContractAction.ts +9 -10
  158. package/src/Actions/ERC721MintAction.ts +12 -13
  159. package/src/Actions/EventAction.test.ts +45 -54
  160. package/src/Actions/EventAction.ts +100 -100
  161. package/src/AllowLists/SimpleAllowList.ts +5 -5
  162. package/src/AllowLists/SimpleDenyList.ts +6 -6
  163. package/src/Boost.ts +19 -0
  164. package/src/BoostCore.test.ts +117 -1
  165. package/src/BoostCore.ts +121 -57
  166. package/src/BoostRegistry.ts +29 -21
  167. package/src/Budgets/ManagedBudget.ts +18 -18
  168. package/src/Budgets/VestingBudget.ts +23 -23
  169. package/src/Deployable/Contract.ts +4 -5
  170. package/src/Deployable/Deployable.ts +1 -1
  171. package/src/Deployable/DeployableTarget.ts +5 -5
  172. package/src/Deployable/DeployableTargetWithRBAC.ts +15 -15
  173. package/src/Incentives/AllowListIncentive.ts +12 -12
  174. package/src/Incentives/CGDAIncentive.ts +15 -15
  175. package/src/Incentives/ERC1155Incentive.ts +26 -26
  176. package/src/Incentives/ERC20Incentive.ts +23 -23
  177. package/src/Incentives/ERC20VariableCriteriaIncentive.test.ts +184 -0
  178. package/src/Incentives/ERC20VariableCriteriaIncentive.ts +309 -0
  179. package/src/Incentives/ERC20VariableIncentive.ts +19 -19
  180. package/src/Incentives/Incentive.ts +6 -5
  181. package/src/Incentives/PointsIncentive.test.ts +21 -21
  182. package/src/Incentives/PointsIncentive.ts +14 -14
  183. package/src/Validators/SignerValidator.ts +14 -14
  184. package/src/Validators/Validator.ts +1 -1
  185. package/src/claiming.ts +1 -1
  186. package/src/errors.ts +165 -0
  187. package/src/index.test.ts +117 -33
  188. package/src/index.ts +1 -0
  189. package/src/transfers.ts +1 -1
  190. package/src/utils.ts +1 -1
  191. package/dist/Incentive-DJf-vdyL.js.map +0 -1
  192. package/dist/Incentive-DNwROd1r.cjs.map +0 -1
  193. package/dist/SimpleDenyList-DMlUkmAn.cjs.map +0 -1
  194. package/dist/SimpleDenyList-DvUvmOeE.js.map +0 -1
  195. package/dist/componentInterfaces-BPVR_Ykd.js +0 -13
  196. package/dist/componentInterfaces-BPVR_Ykd.js.map +0 -1
  197. package/dist/componentInterfaces-BfppSIl4.cjs +0 -2
  198. package/dist/componentInterfaces-BfppSIl4.cjs.map +0 -1
  199. package/dist/deployments-BvFcK_eR.js +0 -40
  200. package/dist/deployments-BvFcK_eR.js.map +0 -1
  201. package/dist/deployments-Ho4PnGCS.cjs +0 -2
  202. package/dist/deployments-Ho4PnGCS.cjs.map +0 -1
  203. package/dist/generated-CMQ6ZC2_.cjs +0 -3
  204. package/dist/generated-CMQ6ZC2_.cjs.map +0 -1
  205. package/dist/generated-C_7Jx3YG.js.map +0 -1
@@ -130,8 +130,8 @@ export class ERC20Incentive extends DeployableTarget<
130
130
  *
131
131
  * @public
132
132
  * @async
133
- * @param {?ReadParams<typeof erc20IncentiveAbi, 'owner'>} [params]
134
- * @returns {unknown}
133
+ * @param {?ReadParams} [params]
134
+ * @returns {Promise<Address>}
135
135
  */
136
136
  public async owner(params?: ReadParams<typeof erc20IncentiveAbi, 'owner'>) {
137
137
  return await readErc20IncentiveOwner(this._config, {
@@ -147,7 +147,7 @@ export class ERC20Incentive extends DeployableTarget<
147
147
  *
148
148
  * @public
149
149
  * @async
150
- * @param {?ReadParams<typeof erc20IncentiveAbi, 'currentReward'>} [params]
150
+ * @param {?ReadParams} [params]
151
151
  * @returns {Promise<bigint>} - The current reward
152
152
  */
153
153
  public async currentReward(
@@ -166,7 +166,7 @@ export class ERC20Incentive extends DeployableTarget<
166
166
  *
167
167
  * @public
168
168
  * @async
169
- * @param {?ReadParams<typeof erc20IncentiveAbi, 'claims'>} [params]
169
+ * @param {?ReadParams} [params]
170
170
  * @returns {Promise<bigint>}
171
171
  */
172
172
  public async claims(params?: ReadParams<typeof erc20IncentiveAbi, 'claims'>) {
@@ -184,7 +184,7 @@ export class ERC20Incentive extends DeployableTarget<
184
184
  * @public
185
185
  * @async
186
186
  * @param {Address} address
187
- * @param {?ReadParams<typeof erc20IncentiveAbi, 'claimed'>} [params]
187
+ * @param {?ReadParams} [params]
188
188
  * @returns {Promise<boolean>}
189
189
  */
190
190
  public async claimed(
@@ -204,7 +204,7 @@ export class ERC20Incentive extends DeployableTarget<
204
204
  *
205
205
  * @public
206
206
  * @async
207
- * @param {?ReadParams<typeof erc20IncentiveAbi, 'asset'>} [params]
207
+ * @param {?ReadParams} [params]
208
208
  * @returns {Promise<Address>}
209
209
  */
210
210
  public async asset(params?: ReadParams<typeof erc20IncentiveAbi, 'asset'>) {
@@ -220,7 +220,7 @@ export class ERC20Incentive extends DeployableTarget<
220
220
  *
221
221
  * @public
222
222
  * @async
223
- * @param {?ReadParams<typeof erc20IncentiveAbi, 'strategy'>} [params]
223
+ * @param {?ReadParams} [params]
224
224
  * @returns {Promise<StrategyType>}
225
225
  */
226
226
  public strategy(
@@ -238,7 +238,7 @@ export class ERC20Incentive extends DeployableTarget<
238
238
  *
239
239
  * @public
240
240
  * @async
241
- * @param {?ReadParams<typeof erc20IncentiveAbi, 'reward'>} [params]
241
+ * @param {?ReadParams} [params]
242
242
  * @returns {Promise<bigint>}
243
243
  */
244
244
  public async reward(params?: ReadParams<typeof erc20IncentiveAbi, 'reward'>) {
@@ -254,8 +254,8 @@ export class ERC20Incentive extends DeployableTarget<
254
254
  *
255
255
  * @public
256
256
  * @async
257
- * @param {?ReadParams<typeof erc20IncentiveAbi, 'limit'>} [params]
258
- * @returns {unknown}
257
+ * @param {?ReadParams} [params]
258
+ * @returns {Promise<bigint>}
259
259
  */
260
260
  public async limit(params?: ReadParams<typeof erc20IncentiveAbi, 'limit'>) {
261
261
  return await readErc20IncentiveLimit(this._config, {
@@ -271,7 +271,7 @@ export class ERC20Incentive extends DeployableTarget<
271
271
  * @public
272
272
  * @async
273
273
  * @param {bigint} i - Index of address
274
- * @param {?ReadParams<typeof erc20IncentiveAbi, 'entries'>} [params]
274
+ * @param {?ReadParams} [params]
275
275
  * @returns {Promise<Address>}
276
276
  */
277
277
  public async entries(
@@ -292,7 +292,7 @@ export class ERC20Incentive extends DeployableTarget<
292
292
  * @public
293
293
  * @async
294
294
  * @param {ClaimPayload} payload
295
- * @param {?WriteParams<typeof erc20IncentiveAbi, 'claim'>} [params]
295
+ * @param {?WriteParams} [params]
296
296
  * @returns {Promise<boolean>} - Returns true if successfully claimed
297
297
  */
298
298
  protected async claim(
@@ -308,8 +308,8 @@ export class ERC20Incentive extends DeployableTarget<
308
308
  * @public
309
309
  * @async
310
310
  * @param {ClaimPayload} payload
311
- * @param {?WriteParams<typeof erc20IncentiveAbi, 'claim'>} [params]
312
- * @returns {Promise<boolean>} - Returns true if successfully claimed
311
+ * @param {?WriteParams} [params]
312
+ * @returns {Promise<{ hash: `0x${string}`; result: boolean; }>} - Returns true if successfully claimed
313
313
  */
314
314
  protected async claimRaw(
315
315
  payload: ClaimPayload,
@@ -335,7 +335,7 @@ export class ERC20Incentive extends DeployableTarget<
335
335
  * @public
336
336
  * @async
337
337
  * @param {ClaimPayload} payload
338
- * @param {?WriteParams<typeof erc20IncentiveAbi, 'clawback'>} [params]
338
+ * @param {?WriteParams} [params]
339
339
  * @returns {Promise<boolean>} - True if the assets were successfully clawbacked
340
340
  */
341
341
  public async clawback(
@@ -351,8 +351,8 @@ export class ERC20Incentive extends DeployableTarget<
351
351
  * @public
352
352
  * @async
353
353
  * @param {ClaimPayload} payload
354
- * @param {?WriteParams<typeof erc20IncentiveAbi, 'clawback'>} [params]
355
- * @returns {Promise<boolean>} - True if the assets were successfully clawbacked
354
+ * @param {?WriteParams} [params]
355
+ * @returns {Promise<{ hash: `0x${string}`; result: boolean; }>} - True if the assets were successfully clawbacked
356
356
  */
357
357
  public async clawbackRaw(
358
358
  payload: ClaimPayload,
@@ -378,8 +378,8 @@ export class ERC20Incentive extends DeployableTarget<
378
378
  * @public
379
379
  * @async
380
380
  * @param {ClaimPayload} payload
381
- * @param {?ReadParams<typeof erc20IncentiveAbi, 'isClaimable'>} [params]
382
- * @returns {unknown} = True if the incentive is claimable based on the data payload
381
+ * @param {?ReadParams} [params]
382
+ * @returns {Promise<boolean>} = True if the incentive is claimable based on the data payload
383
383
  */
384
384
  public async isClaimable(
385
385
  payload: ClaimPayload,
@@ -398,7 +398,7 @@ export class ERC20Incentive extends DeployableTarget<
398
398
  *
399
399
  * @public
400
400
  * @async
401
- * @param {?WriteParams<typeof erc20IncentiveAbi, 'drawRaffle'>} [params]
401
+ * @param {?WriteParams} [params]
402
402
  * @returns {Promise<void>}
403
403
  */
404
404
  public async drawRaffle(
@@ -412,8 +412,8 @@ export class ERC20Incentive extends DeployableTarget<
412
412
  *
413
413
  * @public
414
414
  * @async
415
- * @param {?WriteParams<typeof erc20IncentiveAbi, 'drawRaffle'>} [params]
416
- * @returns {Promise<void>}
415
+ * @param {?WriteParams} [params]
416
+ * @returns {Promise<{ hash: `0x${string}`; result: void; }>}
417
417
  */
418
418
  public async drawRaffleRaw(
419
419
  params?: WriteParams<typeof erc20IncentiveAbi, 'drawRaffle'>,
@@ -464,7 +464,7 @@ export class ERC20Incentive extends DeployableTarget<
464
464
  * @param {StrategyType} param0.strategy - The type of disbursement strategy for the incentive. `StrategyType.MINT` is not supported for `ERC20Incentives`
465
465
  * @param {bigint} param0.reward - The amount of the asset to distribute.
466
466
  * @param {bigint} param0.limit - How many times can this incentive be claimed.
467
- * @returns {*}
467
+ * @returns {Hex}
468
468
  */
469
469
  export function prepareERC20IncentivePayload({
470
470
  asset,
@@ -0,0 +1,184 @@
1
+ import { Mock } from 'node:test';
2
+ import { selectors as eventSelectors } from '@boostxyz/signatures/events';
3
+ import { selectors as funcSelectors } from '@boostxyz/signatures/functions';
4
+ import type { MockERC20 } from '@boostxyz/test/MockERC20';
5
+ import type { MockERC721 } from '@boostxyz/test/MockERC721';
6
+ import { accounts } from '@boostxyz/test/accounts';
7
+ import {
8
+ type BudgetFixtures,
9
+ type Fixtures,
10
+ defaultOptions,
11
+ deployFixtures,
12
+ freshBoost,
13
+ fundBudget,
14
+ fundErc20,
15
+ fundErc721,
16
+ } from '@boostxyz/test/helpers';
17
+ import { loadFixture } from '@nomicfoundation/hardhat-network-helpers';
18
+ import { type Hex, isAddress, parseEther } from 'viem';
19
+ import { beforeAll, beforeEach, describe, expect, test } from 'vitest';
20
+ import { SignatureType } from '../Actions/EventAction';
21
+ import type { Boost } from '../Boost';
22
+ import type {
23
+ ERC20VariableCriteriaIncentive,
24
+ ERC20VariableCriteriaIncentivePayload,
25
+ IncentiveCriteria,
26
+ } from './ERC20VariableCriteriaIncentive';
27
+
28
+ /**
29
+ * A basic ERC721 mint scalar criteria for testing
30
+ *
31
+ * @param {MockERC721} erc721 - The ERC721 contract
32
+ * @returns {IncentiveCriteria} - Returns a basic incentive criteria
33
+ */
34
+ export function basicErc721TransferScalarCriteria(
35
+ erc721: MockERC721,
36
+ ): IncentiveCriteria {
37
+ return {
38
+ criteriaType: SignatureType.FUNC,
39
+ signature: funcSelectors['transferFrom(address,address,uint256)'] as Hex, // Function selector for mint
40
+ fieldIndex: 2, // Field where the scalar value resides
41
+ targetContract: erc721.assertValidAddress(),
42
+ };
43
+ }
44
+
45
+ /**
46
+ * A basic ERC721 mint scalar criteria for testing
47
+ *
48
+ * @param {MockERC721} erc721 - The ERC721 contract
49
+ * @returns {IncentiveCriteria} - Returns a basic incentive criteria
50
+ */
51
+ export function basicErc721MintScalarCriteria(
52
+ erc721: MockERC721,
53
+ ): IncentiveCriteria {
54
+ return {
55
+ criteriaType: SignatureType.EVENT,
56
+ signature: eventSelectors[
57
+ 'Transfer(address indexed,address indexed,uint256 indexed)'
58
+ ] as Hex, // Function selector for mint
59
+ fieldIndex: 2, // Field where the scalar value resides
60
+ targetContract: erc721.assertValidAddress(),
61
+ };
62
+ }
63
+
64
+ /**
65
+ * A basic ERC721 mint scalar payload for testing
66
+ *
67
+ * @param {MockERC721} erc721 - The ERC721 contract
68
+ * @returns {ERC20VariableCriteriaIncentivePayload} - Returns a full variable criteria incentive payload
69
+ */
70
+ export function basicErc721TransferScalarPayload(
71
+ erc721: MockERC721,
72
+ ): ERC20VariableCriteriaIncentivePayload {
73
+ return {
74
+ asset: erc721.assertValidAddress(),
75
+ reward: 1n,
76
+ limit: 1n,
77
+ criteria: basicErc721TransferScalarCriteria(erc721),
78
+ };
79
+ }
80
+
81
+ let fixtures: Fixtures,
82
+ erc20: MockERC20,
83
+ erc721: MockERC721,
84
+ erc20Incentive: ERC20VariableCriteriaIncentive,
85
+ budgets: BudgetFixtures,
86
+ boost: Boost;
87
+
88
+ describe('ERC20VariableCriteriaIncentive', () => {
89
+ beforeAll(async () => {
90
+ fixtures = await loadFixture(deployFixtures(defaultOptions));
91
+ });
92
+
93
+ beforeEach(async () => {
94
+ budgets = await loadFixture(fundBudget(defaultOptions, fixtures));
95
+ erc20 = await loadFixture(fundErc20(defaultOptions));
96
+ erc721 = await loadFixture(fundErc721(defaultOptions));
97
+ erc20Incentive = fixtures.core.ERC20VariableCriteriaIncentive({
98
+ asset: budgets.erc20.assertValidAddress(),
99
+ reward: 1n,
100
+ limit: 1n,
101
+ criteria: basicErc721TransferScalarCriteria(erc721),
102
+ });
103
+
104
+ boost = await freshBoost(fixtures, {
105
+ budget: budgets.budget,
106
+ incentives: [erc20Incentive],
107
+ });
108
+ expect(isAddress(boost.incentives[0]!.assertValidAddress())).toBe(true);
109
+ });
110
+
111
+ describe('getIncentiveCriteria', () => {
112
+ test('should fetch incentive criteria successfully', async () => {
113
+ const incentive = boost.incentives[0] as ERC20VariableCriteriaIncentive;
114
+ const criteria = await incentive.getIncentiveCriteria();
115
+ expect(criteria).toMatchObject({
116
+ criteriaType: SignatureType.FUNC,
117
+ signature: expect.any(String),
118
+ fieldIndex: expect.any(Number),
119
+ targetContract: expect.any(String),
120
+ });
121
+ });
122
+ });
123
+
124
+ describe('getIncentiveScalar', () => {
125
+ test('should return a valid scalar for function-based criteria', async () => {
126
+ const recipient = accounts[1].account;
127
+
128
+ const { hash } = await erc721.transferFromRaw(
129
+ accounts[0].account,
130
+ recipient,
131
+ 1n,
132
+ );
133
+ const scalar = await erc20Incentive.getIncentiveScalar({ hash });
134
+
135
+ expect(scalar).toBe(1n);
136
+ });
137
+
138
+ test('should return a valid scalar for event-based criteria', async () => {
139
+ erc20Incentive = fixtures.core.ERC20VariableCriteriaIncentive({
140
+ asset: budgets.erc20.assertValidAddress(),
141
+ reward: 1n,
142
+ limit: 1n,
143
+ criteria: basicErc721MintScalarCriteria(erc721),
144
+ });
145
+
146
+ boost = await freshBoost(fixtures, {
147
+ budget: budgets.budget,
148
+ incentives: [erc20Incentive],
149
+ });
150
+ const recipient = accounts[1].account;
151
+ const { hash } = await erc721.transferFromRaw(
152
+ accounts[0].account,
153
+ recipient,
154
+ 1n,
155
+ );
156
+ const scalar = await erc20Incentive.getIncentiveScalar({ hash });
157
+
158
+ expect(scalar).toBe(1n);
159
+ });
160
+
161
+ test('should throw NoMatchingLogsError for event criteria with no matching logs', async () => {
162
+ const recipient = accounts[1].account;
163
+
164
+ const { hash } = await erc20.mintRaw(recipient, parseEther('100'));
165
+
166
+ try {
167
+ await erc20Incentive.getIncentiveScalar({ hash });
168
+ } catch (e) {
169
+ expect((e as Error).name).toBe('DecodedArgsError');
170
+ }
171
+ });
172
+
173
+ test('should throw DecodedArgsError for invalid function-based data', async () => {
174
+ const recipient = accounts[1].account;
175
+ const { hash } = await erc20.mintRaw(recipient, parseEther('100'));
176
+
177
+ try {
178
+ await erc20Incentive.getIncentiveScalar({ hash });
179
+ } catch (e) {
180
+ expect((e as Error).name).toBe('DecodedArgsError');
181
+ }
182
+ });
183
+ });
184
+ });
@@ -0,0 +1,309 @@
1
+ import {
2
+ erc20VariableCriteriaIncentiveAbi,
3
+ readErc20VariableCriteriaIncentiveGetIncentiveCriteria,
4
+ } from '@boostxyz/evm';
5
+ import { bytecode } from '@boostxyz/evm/artifacts/contracts/incentives/ERC20VariableCriteriaIncentive.sol/ERC20VariableCriteriaIncentive.json';
6
+ import events from '@boostxyz/signatures/events';
7
+ import functions from '@boostxyz/signatures/functions';
8
+ import { getTransaction, getTransactionReceipt } from '@wagmi/core';
9
+ import {
10
+ type AbiEvent,
11
+ type AbiFunction,
12
+ type Address,
13
+ type Hex,
14
+ type Log,
15
+ decodeFunctionData,
16
+ encodeAbiParameters,
17
+ parseEventLogs,
18
+ } from 'viem';
19
+ import { ERC20VariableCriteriaIncentive as ERC20VariableCriteriaIncentiveBases } from '../../dist/deployments.json';
20
+ import { SignatureType } from '../Actions/EventAction';
21
+ import type {
22
+ DeployableOptions,
23
+ GenericDeployableParams,
24
+ } from '../Deployable/Deployable';
25
+ import { DeployableTarget } from '../Deployable/DeployableTarget';
26
+ import {
27
+ DecodedArgsError,
28
+ FieldActionValidationError,
29
+ IncentiveCriteriaNotFoundError,
30
+ InvalidCriteriaTypeError,
31
+ NoMatchingLogsError,
32
+ } from '../errors';
33
+ import type { ReadParams } from '../utils';
34
+ import { ERC20VariableIncentive } from './ERC20VariableIncentive';
35
+
36
+ export interface ERC20VariableCriteriaIncentivePayload {
37
+ /**
38
+ * The address of the incentivized asset.
39
+ *
40
+ * @type {Address}
41
+ */
42
+ asset: Address;
43
+ /**
44
+ * The amount of the asset to distribute as reward.
45
+ *
46
+ * @type {bigint}
47
+ */
48
+ reward: bigint;
49
+ /**
50
+ * The total spending limit of the asset that will be distributed.
51
+ *
52
+ * @type {bigint}
53
+ */
54
+ limit: bigint;
55
+ /**
56
+ * The criteria for the incentive that determines how the reward is distributed.
57
+ *
58
+ * @type {IncentiveCriteria}
59
+ */
60
+ criteria: IncentiveCriteria;
61
+ }
62
+
63
+ export interface IncentiveCriteria {
64
+ /**
65
+ * The type of criteria used, either function signature or event signature.
66
+ *
67
+ * @type {SignatureType}
68
+ */
69
+ criteriaType: SignatureType;
70
+ /**
71
+ * The function or event signature used for criteria matching.
72
+ *
73
+ * @type {Hex}
74
+ */
75
+ signature: Hex;
76
+ /**
77
+ * The index of the field from where the scalar value is extracted.
78
+ *
79
+ * @type {number}
80
+ */
81
+ fieldIndex: number;
82
+ /**
83
+ * The address of the contract where the event/function is called/emitted.
84
+ *
85
+ * @type {Address}
86
+ */
87
+ targetContract: Address;
88
+ }
89
+
90
+ export interface ReadIncentiveCriteriaParams
91
+ extends ReadParams<
92
+ typeof erc20VariableCriteriaIncentiveAbi,
93
+ 'getIncentiveCriteria'
94
+ > {}
95
+
96
+ export interface GetIncentiveScalarParams {
97
+ hash: Hex;
98
+ }
99
+
100
+ /**
101
+ * Extended ERC20 Variable Criteria Incentive class that fetches incentive criteria and scalar
102
+ */
103
+ export class ERC20VariableCriteriaIncentive extends DeployableTarget<
104
+ ERC20VariableCriteriaIncentivePayload,
105
+ typeof erc20VariableCriteriaIncentiveAbi
106
+ > {
107
+ public override readonly abi = erc20VariableCriteriaIncentiveAbi;
108
+ /**
109
+ * @inheritdoc
110
+ *
111
+ * @public
112
+ * @static
113
+ * @type {Record<number, Address>}
114
+ */
115
+ public static override bases: Record<number, Address> = {
116
+ ...(ERC20VariableCriteriaIncentiveBases as Record<number, Address>),
117
+ };
118
+
119
+ /**
120
+ *Functions from the ERC20VariableIncentive contract
121
+ */
122
+
123
+ /**
124
+ * Fetches the IncentiveCriteria struct from the contract
125
+ *
126
+ * @returns {Promise<IncentiveCriteria>} Incentive criteria structure
127
+ * @throws {IncentiveCriteriaNotFoundError}
128
+ */
129
+ public async getIncentiveCriteria(): Promise<IncentiveCriteria> {
130
+ try {
131
+ const criteria =
132
+ await readErc20VariableCriteriaIncentiveGetIncentiveCriteria(
133
+ this._config,
134
+ {
135
+ address: this.assertValidAddress(),
136
+ },
137
+ );
138
+
139
+ return criteria;
140
+ } catch (e) {
141
+ throw new IncentiveCriteriaNotFoundError(e as Error);
142
+ }
143
+ }
144
+
145
+ /**
146
+ * Fetches the incentive scalar from a transaction hash
147
+ *
148
+ * @param {GetIncentiveScalarParams} params
149
+ * @returns {Promise<bigint>}
150
+ * @throws {InvalidCriteriaTypeError | NoMatchingLogsError | DecodedArgsError}
151
+ */
152
+ public async getIncentiveScalar({
153
+ hash,
154
+ }: GetIncentiveScalarParams): Promise<bigint> {
155
+ const criteria = await this.getIncentiveCriteria();
156
+ const transaction = await getTransaction(this._config, {
157
+ hash,
158
+ });
159
+ if (criteria.criteriaType === SignatureType.EVENT) {
160
+ const transactionReceipt = await getTransactionReceipt(this._config, {
161
+ hash,
162
+ });
163
+
164
+ const logs = transactionReceipt.logs;
165
+
166
+ if (logs.length === 0) {
167
+ throw new NoMatchingLogsError(
168
+ `No logs found for event signature ${criteria.signature}`,
169
+ );
170
+ }
171
+
172
+ // Decode the event log
173
+ try {
174
+ // Decode function data
175
+ const eventAbi = (events.abi as Record<Hex, AbiEvent>)[
176
+ criteria.signature
177
+ ] as AbiEvent;
178
+ const decodedEvents = parseEventLogs({
179
+ abi: [eventAbi],
180
+ logs,
181
+ });
182
+ if (decodedEvents == undefined || decodedEvents.length === 0) {
183
+ throw new NoMatchingLogsError(
184
+ `No logs found for event signature ${criteria.signature}`,
185
+ );
186
+ }
187
+ const scalarValue = (decodedEvents[0]?.args as string[])[
188
+ criteria.fieldIndex
189
+ ];
190
+
191
+ if (scalarValue === undefined) {
192
+ throw new DecodedArgsError(
193
+ `Decoded argument at index ${criteria.fieldIndex} is undefined`,
194
+ );
195
+ }
196
+ return BigInt(scalarValue);
197
+ } catch (e) {
198
+ throw new DecodedArgsError(
199
+ `Failed to decode event log for signature ${criteria.signature}: ${(e as Error).message}`,
200
+ );
201
+ }
202
+ } else if (criteria.criteriaType === SignatureType.FUNC) {
203
+ // Fetch the transaction data
204
+ try {
205
+ // Decode function data
206
+ const func = (functions.abi as Record<Hex, AbiFunction>)[
207
+ criteria.signature
208
+ ] as AbiFunction;
209
+
210
+ const decodedFunction = decodeFunctionData({
211
+ abi: [func],
212
+ data: transaction.input,
213
+ });
214
+ const scalarValue = decodedFunction.args[criteria.fieldIndex] as string;
215
+ if (scalarValue === undefined || scalarValue === null) {
216
+ throw new DecodedArgsError(
217
+ `Decoded argument at index ${criteria.fieldIndex} is undefined`,
218
+ );
219
+ }
220
+ return BigInt(scalarValue);
221
+ } catch (e) {
222
+ throw new DecodedArgsError(
223
+ `Failed to decode function data for signature ${criteria.signature}: ${(e as Error).message}`,
224
+ );
225
+ }
226
+ } else {
227
+ throw new InvalidCriteriaTypeError(
228
+ `Invalid criteria type ${criteria.criteriaType}`,
229
+ );
230
+ }
231
+ }
232
+ /**
233
+ * @inheritdoc
234
+ *
235
+ * @public
236
+ * @param {?ERC20VariableCriteriaIncentivePayload} [_payload]
237
+ * @param {?DeployableOptions} [_options]
238
+ * @returns {GenericDeployableParams}
239
+ */
240
+ public override buildParameters(
241
+ _payload?: ERC20VariableCriteriaIncentivePayload,
242
+ _options?: DeployableOptions,
243
+ ): GenericDeployableParams {
244
+ const [payload, options] = this.validateDeploymentConfig(
245
+ _payload,
246
+ _options,
247
+ );
248
+ return {
249
+ abi: erc20VariableCriteriaIncentiveAbi,
250
+ bytecode: bytecode as Hex,
251
+ args: [prepareERC20VariableCriteriaIncentivePayload(payload)],
252
+ ...this.optionallyAttachAccount(options.account),
253
+ };
254
+ }
255
+ }
256
+
257
+ /**
258
+ *
259
+ *
260
+ * @param {InitPayloadExtended} param0
261
+ * @param {Address} param0.asset - The address of the ERC20 asset to incentivize.
262
+ * @param {bigint} param0.reward - The reward amount to distribute per action.
263
+ * @param {bigint} param0.limit - The total limit of the asset distribution.
264
+ * @param {IncentiveCriteria} param0.criteria - The incentive criteria for reward distribution.
265
+ * @returns {Hex}
266
+ */
267
+ export function prepareERC20VariableCriteriaIncentivePayload({
268
+ asset,
269
+ reward,
270
+ limit,
271
+ criteria,
272
+ }: ERC20VariableCriteriaIncentivePayload) {
273
+ return encodeAbiParameters(
274
+ [
275
+ {
276
+ type: 'tuple',
277
+ name: 'initPayloadExtended',
278
+ components: [
279
+ { type: 'address', name: 'asset' },
280
+ { type: 'uint256', name: 'reward' },
281
+ { type: 'uint256', name: 'limit' },
282
+ {
283
+ type: 'tuple',
284
+ name: 'criteria',
285
+ components: [
286
+ { type: 'uint8', name: 'criteriaType' },
287
+ { type: 'bytes32', name: 'signature' },
288
+ { type: 'uint8', name: 'fieldIndex' },
289
+ { type: 'address', name: 'targetContract' },
290
+ ],
291
+ },
292
+ ],
293
+ },
294
+ ],
295
+ [
296
+ {
297
+ asset: asset,
298
+ reward: reward,
299
+ limit: limit,
300
+ criteria: {
301
+ criteriaType: criteria.criteriaType,
302
+ signature: criteria.signature,
303
+ fieldIndex: criteria.fieldIndex,
304
+ targetContract: criteria.targetContract,
305
+ },
306
+ },
307
+ ],
308
+ );
309
+ }