@boostxyz/sdk 1.1.0-alpha.23 → 2.0.0-alpha.25

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 (134) hide show
  1. package/dist/Actions/Action.cjs +1 -1
  2. package/dist/Actions/Action.js +7 -7
  3. package/dist/Actions/EventAction.cjs +1 -1
  4. package/dist/Actions/EventAction.cjs.map +1 -1
  5. package/dist/Actions/EventAction.d.ts +32 -5
  6. package/dist/Actions/EventAction.d.ts.map +1 -1
  7. package/dist/Actions/EventAction.js +164 -137
  8. package/dist/Actions/EventAction.js.map +1 -1
  9. package/dist/AllowLists/AllowList.cjs +1 -1
  10. package/dist/AllowLists/AllowList.js +10 -10
  11. package/dist/AllowLists/SimpleAllowList.cjs +1 -1
  12. package/dist/AllowLists/SimpleAllowList.js +10 -10
  13. package/dist/AllowLists/SimpleDenyList.cjs +1 -1
  14. package/dist/AllowLists/SimpleDenyList.js +3 -3
  15. package/dist/Auth/PassthroughAuth.cjs +1 -1
  16. package/dist/Auth/PassthroughAuth.js +1 -1
  17. package/dist/BoostCore.cjs +2 -1
  18. package/dist/BoostCore.cjs.map +1 -1
  19. package/dist/BoostCore.d.ts +564 -1
  20. package/dist/BoostCore.d.ts.map +1 -1
  21. package/dist/BoostCore.js +1322 -29
  22. package/dist/BoostCore.js.map +1 -1
  23. package/dist/BoostRegistry.cjs +1 -1
  24. package/dist/BoostRegistry.js +27 -27
  25. package/dist/Budgets/Budget.cjs +1 -1
  26. package/dist/Budgets/Budget.js +2 -2
  27. package/dist/Budgets/ManagedBudget.cjs +1 -1
  28. package/dist/Budgets/ManagedBudget.js +23 -23
  29. package/dist/Deployable/DeployableTarget.cjs +1 -1
  30. package/dist/Deployable/DeployableTarget.js +1 -1
  31. package/dist/Deployable/DeployableTargetWithRBAC.cjs +1 -1
  32. package/dist/Deployable/DeployableTargetWithRBAC.js +23 -23
  33. package/dist/Incentives/AllowListIncentive.cjs +1 -1
  34. package/dist/Incentives/AllowListIncentive.js +8 -8
  35. package/dist/Incentives/CGDAIncentive.cjs +1 -1
  36. package/dist/Incentives/CGDAIncentive.js +12 -12
  37. package/dist/Incentives/ERC20Incentive.cjs +1 -1
  38. package/dist/Incentives/ERC20Incentive.js +16 -16
  39. package/dist/Incentives/ERC20VariableCriteriaIncentive.cjs +2 -0
  40. package/dist/Incentives/ERC20VariableCriteriaIncentive.cjs.map +1 -0
  41. package/dist/Incentives/ERC20VariableCriteriaIncentive.d.ts +42 -15
  42. package/dist/Incentives/ERC20VariableCriteriaIncentive.d.ts.map +1 -1
  43. package/dist/Incentives/ERC20VariableCriteriaIncentive.js +188 -0
  44. package/dist/Incentives/ERC20VariableCriteriaIncentive.js.map +1 -0
  45. package/dist/Incentives/ERC20VariableIncentive.cjs +2 -0
  46. package/dist/Incentives/ERC20VariableIncentive.cjs.map +1 -0
  47. package/dist/Incentives/ERC20VariableIncentive.d.ts +7 -5
  48. package/dist/Incentives/ERC20VariableIncentive.d.ts.map +1 -1
  49. package/dist/{Incentive-rM5nKznp.js → Incentives/ERC20VariableIncentive.js} +42 -67
  50. package/dist/Incentives/ERC20VariableIncentive.js.map +1 -0
  51. package/dist/Incentives/Incentive.cjs +1 -1
  52. package/dist/Incentives/Incentive.cjs.map +1 -1
  53. package/dist/Incentives/Incentive.d.ts +552 -3
  54. package/dist/Incentives/Incentive.d.ts.map +1 -1
  55. package/dist/Incentives/Incentive.js +40 -16
  56. package/dist/Incentives/Incentive.js.map +1 -1
  57. package/dist/Incentives/PointsIncentive.cjs +1 -1
  58. package/dist/Incentives/PointsIncentive.js +8 -8
  59. package/dist/{SimpleDenyList-DNj5qDWM.cjs → SimpleDenyList-BdlpZdDz.cjs} +2 -2
  60. package/dist/{SimpleDenyList-DNj5qDWM.cjs.map → SimpleDenyList-BdlpZdDz.cjs.map} +1 -1
  61. package/dist/{SimpleDenyList-BDXpY74P.js → SimpleDenyList-D0cyVUVv.js} +16 -16
  62. package/dist/{SimpleDenyList-BDXpY74P.js.map → SimpleDenyList-D0cyVUVv.js.map} +1 -1
  63. package/dist/Validators/LimitedSignerValidator.cjs +2 -0
  64. package/dist/Validators/LimitedSignerValidator.cjs.map +1 -0
  65. package/dist/Validators/LimitedSignerValidator.d.ts +806 -0
  66. package/dist/Validators/LimitedSignerValidator.d.ts.map +1 -0
  67. package/dist/Validators/LimitedSignerValidator.js +299 -0
  68. package/dist/Validators/LimitedSignerValidator.js.map +1 -0
  69. package/dist/Validators/SignerValidator.cjs +1 -1
  70. package/dist/Validators/SignerValidator.cjs.map +1 -1
  71. package/dist/Validators/SignerValidator.d.ts +2 -2
  72. package/dist/Validators/SignerValidator.js +5 -5
  73. package/dist/Validators/SignerValidator.js.map +1 -1
  74. package/dist/Validators/Validator.cjs +1 -1
  75. package/dist/Validators/Validator.cjs.map +1 -1
  76. package/dist/Validators/Validator.d.ts +22 -2
  77. package/dist/Validators/Validator.d.ts.map +1 -1
  78. package/dist/Validators/Validator.js +26 -17
  79. package/dist/Validators/Validator.js.map +1 -1
  80. package/dist/{componentInterfaces-BBCFkrZv.js → componentInterfaces-bIVo8eyA.js} +9 -9
  81. package/dist/componentInterfaces-bIVo8eyA.js.map +1 -0
  82. package/dist/{deployments-fJsWblwS.js → deployments-Ccx1MtoK.js} +5 -5
  83. package/dist/deployments-Ccx1MtoK.js.map +1 -0
  84. package/dist/{generated-CsNyWPKA.js → generated-BAKNSOjJ.js} +661 -381
  85. package/dist/generated-BAKNSOjJ.js.map +1 -0
  86. package/dist/generated-Cqn4wS01.cjs +3 -0
  87. package/dist/generated-Cqn4wS01.cjs.map +1 -0
  88. package/dist/index.cjs +1 -1
  89. package/dist/index.d.ts +1 -0
  90. package/dist/index.d.ts.map +1 -1
  91. package/dist/index.js +145 -132
  92. package/dist/index.js.map +1 -1
  93. package/dist/utils.cjs +1 -1
  94. package/dist/utils.cjs.map +1 -1
  95. package/dist/utils.d.ts +10 -0
  96. package/dist/utils.d.ts.map +1 -1
  97. package/dist/utils.js +27 -26
  98. package/dist/utils.js.map +1 -1
  99. package/package.json +21 -5
  100. package/src/Actions/EventAction.test.ts +381 -122
  101. package/src/Actions/EventAction.ts +85 -23
  102. package/src/BoostCore.test.ts +3 -3
  103. package/src/BoostCore.ts +51 -5
  104. package/src/Incentives/AllowListIncentive.test.ts +19 -21
  105. package/src/Incentives/CGDAIncentive.test.ts +20 -22
  106. package/src/Incentives/ERC1155Incentive.test.ts +14 -15
  107. package/src/Incentives/ERC20Incentive.test.ts +17 -19
  108. package/src/Incentives/ERC20VariableCriteriaIncentive.test.ts +62 -10
  109. package/src/Incentives/ERC20VariableCriteriaIncentive.ts +79 -37
  110. package/src/Incentives/ERC20VariableIncentive.test.ts +16 -18
  111. package/src/Incentives/ERC20VariableIncentive.ts +16 -8
  112. package/src/Incentives/Incentive.ts +4 -1
  113. package/src/Incentives/PointsIncentive.test.ts +3 -5
  114. package/src/Validators/LimitedSignerValidator.test.ts +223 -0
  115. package/src/Validators/LimitedSignerValidator.ts +707 -0
  116. package/src/Validators/SignerValidator.test.ts +21 -22
  117. package/src/Validators/SignerValidator.ts +2 -2
  118. package/src/Validators/Validator.test.ts +7 -1
  119. package/src/Validators/Validator.ts +30 -3
  120. package/src/index.test.ts +2 -0
  121. package/src/index.ts +1 -0
  122. package/src/utils.ts +11 -0
  123. package/dist/BoostCore-Btl5BdAs.cjs +0 -3
  124. package/dist/BoostCore-Btl5BdAs.cjs.map +0 -1
  125. package/dist/BoostCore-CD56zbYX.js +0 -2641
  126. package/dist/BoostCore-CD56zbYX.js.map +0 -1
  127. package/dist/Incentive-CcnOIc8L.cjs +0 -2
  128. package/dist/Incentive-CcnOIc8L.cjs.map +0 -1
  129. package/dist/Incentive-rM5nKznp.js.map +0 -1
  130. package/dist/componentInterfaces-BBCFkrZv.js.map +0 -1
  131. package/dist/deployments-fJsWblwS.js.map +0 -1
  132. package/dist/generated-CsNyWPKA.js.map +0 -1
  133. package/dist/generated-DHerxf1y.cjs +0 -3
  134. package/dist/generated-DHerxf1y.cjs.map +0 -1
@@ -1,8 +1,8 @@
1
- import { readMockErc20BalanceOf } from '@boostxyz/evm';
2
- import { loadFixture } from '@nomicfoundation/hardhat-network-helpers';
3
- import { isAddress, pad, parseEther, zeroAddress } from 'viem';
4
- import { beforeAll, beforeEach, describe, expect, test } from 'vitest';
5
- import { accounts } from '@boostxyz/test/accounts';
1
+ import { readMockErc20BalanceOf } from "@boostxyz/evm";
2
+ import { loadFixture } from "@nomicfoundation/hardhat-network-helpers";
3
+ import { isAddress, pad, parseEther, zeroAddress } from "viem";
4
+ import { beforeAll, beforeEach, describe, expect, test } from "vitest";
5
+ import { accounts } from "@boostxyz/test/accounts";
6
6
  import {
7
7
  type BudgetFixtures,
8
8
  type Fixtures,
@@ -10,14 +10,14 @@ import {
10
10
  deployFixtures,
11
11
  freshBoost,
12
12
  fundBudget,
13
- } from '@boostxyz/test/helpers';
14
- import { BOOST_CORE_CLAIM_FEE } from '../BoostCore';
15
- import { StrategyType } from '../claiming';
16
- import { ERC20Incentive } from './ERC20Incentive';
13
+ } from "@boostxyz/test/helpers";
14
+ import { BOOST_CORE_CLAIM_FEE } from "../BoostCore";
15
+ import { StrategyType } from "../claiming";
16
+ import { ERC20Incentive } from "./ERC20Incentive";
17
17
 
18
18
  let fixtures: Fixtures, budgets: BudgetFixtures;
19
19
 
20
- describe('ERC20Incentive', () => {
20
+ describe("ERC20Incentive", () => {
21
21
  beforeAll(async () => {
22
22
  fixtures = await loadFixture(deployFixtures(defaultOptions));
23
23
  });
@@ -26,7 +26,7 @@ describe('ERC20Incentive', () => {
26
26
  budgets = await loadFixture(fundBudget(defaultOptions, fixtures));
27
27
  });
28
28
 
29
- test('can successfully be deployed', async () => {
29
+ test("can successfully be deployed", async () => {
30
30
  const action = new ERC20Incentive(defaultOptions, {
31
31
  asset: zeroAddress,
32
32
  strategy: StrategyType.POOL,
@@ -38,7 +38,7 @@ describe('ERC20Incentive', () => {
38
38
  expect(isAddress(action.assertValidAddress())).toBe(true);
39
39
  });
40
40
 
41
- test('can claim', async () => {
41
+ test("can claim", async () => {
42
42
  // biome-ignore lint/style/noNonNullAssertion: we know this is defined
43
43
  const referrer = accounts.at(1)!.account!,
44
44
  // biome-ignore lint/style/noNonNullAssertion: we know this is defined
@@ -57,12 +57,11 @@ describe('ERC20Incentive', () => {
57
57
 
58
58
  const claimant = trustedSigner.account;
59
59
  const incentiveData = erc20Incentive.buildClaimData();
60
- const incentiveQuantity = 1;
61
60
  const claimDataPayload = await boost.validator.encodeClaimData({
62
61
  signer: trustedSigner,
63
62
  incentiveData,
64
63
  chainId: defaultOptions.config.chains[0].id,
65
- incentiveQuantity,
64
+ incentiveQuantity: boost.incentives.length,
66
65
  claimant,
67
66
  boostId: boost.id,
68
67
  });
@@ -82,7 +81,7 @@ describe('ERC20Incentive', () => {
82
81
  ).toBe(1n);
83
82
  });
84
83
 
85
- test('cannot claim twice', async () => {
84
+ test("cannot claim twice", async () => {
86
85
  // biome-ignore lint/style/noNonNullAssertion: we know this is defined
87
86
  const referrer = accounts.at(1)!.account!;
88
87
  // biome-ignore lint/style/noNonNullAssertion: we know this is defined
@@ -100,13 +99,12 @@ describe('ERC20Incentive', () => {
100
99
  });
101
100
 
102
101
  const claimant = trustedSigner.account;
103
- const incentiveData = pad('0xdef456232173821931823712381232131391321934');
104
- const incentiveQuantity = 1;
102
+ const incentiveData = pad("0xdef456232173821931823712381232131391321934");
105
103
  const claimDataPayload = await boost.validator.encodeClaimData({
106
104
  signer: trustedSigner,
107
105
  incentiveData,
108
106
  chainId: defaultOptions.config.chains[0].id,
109
- incentiveQuantity,
107
+ incentiveQuantity: boost.incentives.length,
110
108
  claimant,
111
109
  boostId: boost.id,
112
110
  });
@@ -124,7 +122,7 @@ describe('ERC20Incentive', () => {
124
122
  0n,
125
123
  referrer,
126
124
  claimDataPayload,
127
- { value: parseEther('0.000075') },
125
+ { value: parseEther("0.000075") },
128
126
  );
129
127
  } catch (e) {
130
128
  expect(e).toBeInstanceOf(Error);
@@ -1,4 +1,3 @@
1
- import { Mock } from 'node:test';
2
1
  import { selectors as eventSelectors } from '@boostxyz/signatures/events';
3
2
  import { selectors as funcSelectors } from '@boostxyz/signatures/functions';
4
3
  import type { MockERC20 } from '@boostxyz/test/MockERC20';
@@ -15,15 +14,17 @@ import {
15
14
  fundErc721,
16
15
  } from '@boostxyz/test/helpers';
17
16
  import { loadFixture } from '@nomicfoundation/hardhat-network-helpers';
18
- import { type Hex, isAddress, parseEther } from 'viem';
17
+ import { type Hex, isAddress, parseEther, zeroAddress, zeroHash } from 'viem';
19
18
  import { beforeAll, beforeEach, describe, expect, test } from 'vitest';
20
19
  import { SignatureType } from '../Actions/EventAction';
21
20
  import type { Boost } from '../Boost';
22
- import type {
23
- ERC20VariableCriteriaIncentive,
24
- ERC20VariableCriteriaIncentivePayload,
25
- IncentiveCriteria,
21
+ import {
22
+ type ERC20VariableCriteriaIncentive,
23
+ type ERC20VariableCriteriaIncentivePayload,
24
+ type IncentiveCriteria,
25
+ gasRebateIncentiveCriteria,
26
26
  } from './ERC20VariableCriteriaIncentive';
27
+ import { allKnownSignatures } from '@boostxyz/test/allKnownSignatures';
27
28
 
28
29
  /**
29
30
  * A basic ERC721 mint scalar criteria for testing
@@ -130,7 +131,11 @@ describe('ERC20VariableCriteriaIncentive', () => {
130
131
  recipient,
131
132
  1n,
132
133
  );
133
- const scalar = await erc20Incentive.getIncentiveScalar({ hash });
134
+ const scalar = await erc20Incentive.getIncentiveScalar({
135
+ hash,
136
+ chainId: 31337,
137
+ knownSignatures: allKnownSignatures
138
+ });
134
139
 
135
140
  expect(scalar).toBe(1n);
136
141
  });
@@ -153,18 +158,61 @@ describe('ERC20VariableCriteriaIncentive', () => {
153
158
  recipient,
154
159
  1n,
155
160
  );
156
- const scalar = await erc20Incentive.getIncentiveScalar({ hash });
161
+ const scalar = await erc20Incentive.getIncentiveScalar({
162
+ hash,
163
+ chainId: 31337,
164
+ knownSignatures: allKnownSignatures
165
+ });
157
166
 
158
167
  expect(scalar).toBe(1n);
159
168
  });
160
169
 
170
+ test('gasRebateIncentiveCriteria generates correct incentive criteria', async () => {
171
+ // Ensure that the gasRebateIncentiveCriteria returns the correct structure
172
+ const gasRebateCriteria = gasRebateIncentiveCriteria();
173
+
174
+ erc20Incentive = fixtures.core.ERC20VariableCriteriaIncentive({
175
+ asset: budgets.erc20.assertValidAddress(),
176
+ reward: 1n,
177
+ limit: 1n,
178
+ criteria: gasRebateCriteria,
179
+ });
180
+
181
+
182
+
183
+ // Validate the returned structure against the expected criteria values
184
+ expect(gasRebateCriteria).toEqual({
185
+ criteriaType: SignatureType.EVENT,
186
+ signature: zeroHash,
187
+ fieldIndex: 255,
188
+ targetContract: zeroAddress,
189
+ });
190
+
191
+ boost = await freshBoost(fixtures, {
192
+ budget: budgets.budget,
193
+ incentives: [erc20Incentive],
194
+ });
195
+
196
+ // Validate that the deployed incentive has the correct criteria set up
197
+ const deployedIncentive = await boost.incentives[0] as ERC20VariableCriteriaIncentive;
198
+ const deployedCriteria = await deployedIncentive.getIncentiveCriteria();
199
+ expect(deployedCriteria.criteriaType).toBe(SignatureType.EVENT);
200
+ expect(deployedCriteria.signature).toBe(zeroHash);
201
+ expect(deployedCriteria.fieldIndex).toBe(255);
202
+ expect(deployedCriteria.targetContract).toBe(zeroAddress);
203
+ });
204
+
161
205
  test('should throw NoMatchingLogsError for event criteria with no matching logs', async () => {
162
206
  const recipient = accounts[1].account;
163
207
 
164
208
  const { hash } = await erc20.mintRaw(recipient, parseEther('100'));
165
209
 
166
210
  try {
167
- await erc20Incentive.getIncentiveScalar({ hash });
211
+ await erc20Incentive.getIncentiveScalar({
212
+ hash,
213
+ chainId: 31337,
214
+ knownSignatures: allKnownSignatures
215
+ });
168
216
  } catch (e) {
169
217
  expect((e as Error).name).toBe('DecodedArgsError');
170
218
  }
@@ -175,7 +223,11 @@ describe('ERC20VariableCriteriaIncentive', () => {
175
223
  const { hash } = await erc20.mintRaw(recipient, parseEther('100'));
176
224
 
177
225
  try {
178
- await erc20Incentive.getIncentiveScalar({ hash });
226
+ await erc20Incentive.getIncentiveScalar({
227
+ hash,
228
+ chainId: 31337,
229
+ knownSignatures: allKnownSignatures
230
+ });
179
231
  } catch (e) {
180
232
  expect((e as Error).name).toBe('DecodedArgsError');
181
233
  }
@@ -3,18 +3,17 @@ import {
3
3
  readErc20VariableCriteriaIncentiveGetIncentiveCriteria,
4
4
  } from '@boostxyz/evm';
5
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
6
  import { getTransaction, getTransactionReceipt } from '@wagmi/core';
9
7
  import {
10
8
  type AbiEvent,
11
9
  type AbiFunction,
12
10
  type Address,
13
11
  type Hex,
14
- type Log,
15
12
  decodeFunctionData,
16
13
  encodeAbiParameters,
17
14
  parseEventLogs,
15
+ zeroAddress,
16
+ zeroHash,
18
17
  } from 'viem';
19
18
  import { ERC20VariableCriteriaIncentive as ERC20VariableCriteriaIncentiveBases } from '../../dist/deployments.json';
20
19
  import { SignatureType } from '../Actions/EventAction';
@@ -22,17 +21,17 @@ import type {
22
21
  DeployableOptions,
23
22
  GenericDeployableParams,
24
23
  } from '../Deployable/Deployable';
25
- import { DeployableTarget } from '../Deployable/DeployableTarget';
26
24
  import {
27
25
  DecodedArgsError,
28
- FieldActionValidationError,
29
26
  IncentiveCriteriaNotFoundError,
30
27
  InvalidCriteriaTypeError,
31
28
  NoMatchingLogsError,
32
29
  } from '../errors';
33
- import type { ReadParams } from '../utils';
30
+ import { CheatCodes, type ReadParams } from '../utils';
34
31
  import { ERC20VariableIncentive } from './ERC20VariableIncentive';
35
32
 
33
+ export { erc20VariableCriteriaIncentiveAbi };
34
+
36
35
  export interface ERC20VariableCriteriaIncentivePayload {
37
36
  /**
38
37
  * The address of the incentivized asset.
@@ -94,16 +93,24 @@ export interface ReadIncentiveCriteriaParams
94
93
  > {}
95
94
 
96
95
  export interface GetIncentiveScalarParams {
96
+ chainId: number;
97
97
  hash: Hex;
98
+ knownSignatures: Record<Hex, AbiFunction | AbiEvent>;
98
99
  }
99
100
 
100
101
  /**
101
102
  * Extended ERC20 Variable Criteria Incentive class that fetches incentive criteria and scalar
103
+ *
104
+ * @export
105
+ * @class ERC20VariableCriteriaIncentive
106
+ * @typedef {ERC20VariableCriteriaIncentive}
107
+ * @extends {ERC20VariableIncentive<ERC20VariableCriteriaIncentivePayload, typeof erc20VariableCriteriaIncentiveAbi>}
102
108
  */
103
- export class ERC20VariableCriteriaIncentive extends DeployableTarget<
109
+ export class ERC20VariableCriteriaIncentive extends ERC20VariableIncentive<
104
110
  ERC20VariableCriteriaIncentivePayload,
105
111
  typeof erc20VariableCriteriaIncentiveAbi
106
112
  > {
113
+ //@ts-expect-error instantiated correctly
107
114
  public override readonly abi = erc20VariableCriteriaIncentiveAbi;
108
115
  /**
109
116
  * @inheritdoc
@@ -124,15 +131,22 @@ export class ERC20VariableCriteriaIncentive extends DeployableTarget<
124
131
  /**
125
132
  * Fetches the IncentiveCriteria struct from the contract
126
133
  *
134
+ * @param {?ReadParams} [params]
127
135
  * @returns {Promise<IncentiveCriteria>} Incentive criteria structure
128
136
  * @throws {IncentiveCriteriaNotFoundError}
129
137
  */
130
- public async getIncentiveCriteria(): Promise<IncentiveCriteria> {
138
+ public async getIncentiveCriteria(
139
+ params?: ReadParams<
140
+ typeof erc20VariableCriteriaIncentiveAbi,
141
+ 'getIncentiveCriteria'
142
+ >,
143
+ ): Promise<IncentiveCriteria> {
131
144
  try {
132
145
  const criteria =
133
146
  await readErc20VariableCriteriaIncentiveGetIncentiveCriteria(
134
147
  this._config,
135
148
  {
149
+ ...params,
136
150
  address: this.assertValidAddress(),
137
151
  },
138
152
  );
@@ -147,21 +161,30 @@ export class ERC20VariableCriteriaIncentive extends DeployableTarget<
147
161
  * Fetches the incentive scalar from a transaction hash
148
162
  *
149
163
  * @param {GetIncentiveScalarParams} params
164
+ * @param {?ReadParams} [params]
150
165
  * @returns {Promise<bigint>}
151
166
  * @throws {InvalidCriteriaTypeError | NoMatchingLogsError | DecodedArgsError}
152
167
  */
153
- public async getIncentiveScalar({
154
- hash,
155
- }: GetIncentiveScalarParams): Promise<bigint> {
156
- const criteria = await this.getIncentiveCriteria();
157
- const transaction = await getTransaction(this._config, {
158
- hash,
159
- });
168
+ public async getIncentiveScalar(
169
+ { chainId, hash, knownSignatures }: GetIncentiveScalarParams,
170
+ params?: ReadParams<
171
+ typeof erc20VariableCriteriaIncentiveAbi,
172
+ 'getIncentiveCriteria'
173
+ >,
174
+ ): Promise<bigint> {
175
+ const criteria = await this.getIncentiveCriteria(params);
160
176
  if (criteria.criteriaType === SignatureType.EVENT) {
161
177
  const transactionReceipt = await getTransactionReceipt(this._config, {
178
+ chainId,
162
179
  hash,
163
180
  });
164
-
181
+ if (criteria.fieldIndex === CheatCodes.GAS_REBATE_INCENTIVE) {
182
+ const totalCost =
183
+ transactionReceipt.gasUsed * transactionReceipt.effectiveGasPrice + // Normal gas cost
184
+ (transactionReceipt.blobGasUsed ?? 0n) *
185
+ (transactionReceipt.blobGasPrice ?? 0n); // Blob gas cost - account for potential undefined values
186
+ return totalCost;
187
+ }
165
188
  const logs = transactionReceipt.logs;
166
189
 
167
190
  if (logs.length === 0) {
@@ -173,9 +196,7 @@ export class ERC20VariableCriteriaIncentive extends DeployableTarget<
173
196
  // Decode the event log
174
197
  try {
175
198
  // Decode function data
176
- const eventAbi = (events.abi as Record<Hex, AbiEvent>)[
177
- criteria.signature
178
- ] as AbiEvent;
199
+ const eventAbi = knownSignatures[criteria.signature] as AbiEvent;
179
200
  const decodedEvents = parseEventLogs({
180
201
  abi: [eventAbi],
181
202
  logs,
@@ -202,12 +223,13 @@ export class ERC20VariableCriteriaIncentive extends DeployableTarget<
202
223
  }
203
224
  } else if (criteria.criteriaType === SignatureType.FUNC) {
204
225
  // Fetch the transaction data
226
+ const transaction = await getTransaction(this._config, {
227
+ chainId,
228
+ hash,
229
+ });
205
230
  try {
206
231
  // Decode function data
207
- const func = (functions.abi as Record<Hex, AbiFunction>)[
208
- criteria.signature
209
- ] as AbiFunction;
210
-
232
+ const func = knownSignatures[criteria.signature] as AbiFunction;
211
233
  const decodedFunction = decodeFunctionData({
212
234
  abi: [func],
213
235
  data: transaction.input,
@@ -230,6 +252,7 @@ export class ERC20VariableCriteriaIncentive extends DeployableTarget<
230
252
  );
231
253
  }
232
254
  }
255
+
233
256
  /**
234
257
  * @inheritdoc
235
258
  *
@@ -253,21 +276,40 @@ export class ERC20VariableCriteriaIncentive extends DeployableTarget<
253
276
  ...this.optionallyAttachAccount(options.account),
254
277
  };
255
278
  }
279
+ }
256
280
 
257
- /**
258
- * Builds the claim data for the ERC20VariableCriteriaIncentive.
259
- *
260
- * @public
261
- * @param {bigint} rewardAmount
262
- * @returns {Hex} Returns the encoded claim data
263
- * @description This function returns the encoded claim data for the ERC20VariableCriteriaIncentive.
264
- */
265
- public buildClaimData(rewardAmount: bigint) {
266
- return encodeAbiParameters(
267
- [{ type: 'uint256', name: 'rewardAmount' }],
268
- [rewardAmount],
269
- );
270
- }
281
+ /**
282
+ * Creates an IncentiveCriteria object representing a gas rebate incentive.
283
+ * This object defines a variable incentive criteria where the criteria will be the gas spent.
284
+ *
285
+ * The criteria uses a signatureType of EVENT, with a special `fieldIndex` of 255 (using CheatCodes enum), which indicates
286
+ * that the entire gas cost of the transaction will be used as the scalar value. If you don't want to
287
+ * rebate the entire gas cost, you can use a reward value on the incentive..
288
+ *
289
+ * - `criteriaType`: EVENT, indicating it's based on event logs.
290
+ * - `signature`: A zeroed signature (0x0000...0000), matching any event.
291
+ * - `fieldIndex`: 255, indicating the use of transaction gas cost using CheatCodes enum.
292
+ * - `targetContract`: A zeroed address (0x0000...0000), applicable to any contract.
293
+ *
294
+ * @returns {IncentiveCriteria} Returns an IncentiveCriteria object for a gas rebate.
295
+ *
296
+ * @example
297
+ * const incentive = gasRebateIncentiveCriteria();
298
+ * const actionPayload = {
299
+ * criteria: incentive,
300
+ * asset: "0xAssetAddress",
301
+ * reward: 0, // Set to zero to rebate the entire gas cost
302
+ * limit: BigInt(1000) // This is the total spend limit for the incentive
303
+ * };
304
+ * deployIncentive(actionPayload);
305
+ */
306
+ export function gasRebateIncentiveCriteria(): IncentiveCriteria {
307
+ return {
308
+ criteriaType: SignatureType.EVENT,
309
+ signature: zeroHash,
310
+ fieldIndex: CheatCodes.GAS_REBATE_INCENTIVE,
311
+ targetContract: zeroAddress,
312
+ };
271
313
  }
272
314
 
273
315
  /**
@@ -1,8 +1,8 @@
1
- import { readMockErc20BalanceOf } from '@boostxyz/evm';
2
- import { loadFixture } from '@nomicfoundation/hardhat-network-helpers';
3
- import { encodeAbiParameters, isAddress, parseEther, zeroAddress } from 'viem';
4
- import { beforeAll, beforeEach, describe, expect, test } from 'vitest';
5
- import { accounts } from '@boostxyz/test/accounts';
1
+ import { readMockErc20BalanceOf } from "@boostxyz/evm";
2
+ import { loadFixture } from "@nomicfoundation/hardhat-network-helpers";
3
+ import { encodeAbiParameters, isAddress, parseEther, zeroAddress } from "viem";
4
+ import { beforeAll, beforeEach, describe, expect, test } from "vitest";
5
+ import { accounts } from "@boostxyz/test/accounts";
6
6
  import {
7
7
  type BudgetFixtures,
8
8
  type Fixtures,
@@ -10,14 +10,14 @@ import {
10
10
  deployFixtures,
11
11
  freshBoost,
12
12
  fundBudget,
13
- } from '@boostxyz/test/helpers';
14
- import { ERC20VariableIncentive } from './ERC20VariableIncentive';
13
+ } from "@boostxyz/test/helpers";
14
+ import { ERC20VariableIncentive } from "./ERC20VariableIncentive";
15
15
 
16
- const BOOST_CORE_CLAIM_FEE = parseEther('0.000075');
16
+ const BOOST_CORE_CLAIM_FEE = parseEther("0.000075");
17
17
 
18
18
  let fixtures: Fixtures, budgets: BudgetFixtures;
19
19
 
20
- describe('ERC20VariableIncentive', () => {
20
+ describe("ERC20VariableIncentive", () => {
21
21
  beforeAll(async () => {
22
22
  fixtures = await loadFixture(deployFixtures(defaultOptions));
23
23
  });
@@ -26,7 +26,7 @@ describe('ERC20VariableIncentive', () => {
26
26
  budgets = await loadFixture(fundBudget(defaultOptions, fixtures));
27
27
  });
28
28
 
29
- test('can successfully be deployed', async () => {
29
+ test("can successfully be deployed", async () => {
30
30
  const action = new ERC20VariableIncentive(defaultOptions, {
31
31
  asset: zeroAddress,
32
32
  reward: 1n,
@@ -37,7 +37,7 @@ describe('ERC20VariableIncentive', () => {
37
37
  expect(isAddress(action.assertValidAddress())).toBe(true);
38
38
  });
39
39
 
40
- test('can claim', async () => {
40
+ test("can claim", async () => {
41
41
  // biome-ignore lint/style/noNonNullAssertion: we know this is defined
42
42
  const referrer = accounts.at(1)!.account!,
43
43
  // biome-ignore lint/style/noNonNullAssertion: we know this is defined
@@ -57,12 +57,11 @@ describe('ERC20VariableIncentive', () => {
57
57
  });
58
58
 
59
59
  const claimant = trustedSigner.account;
60
- const incentiveQuantity = 1;
61
60
  const claimDataPayload = await boost.validator.encodeClaimData({
62
61
  signer: trustedSigner,
63
- incentiveData: erc20VariableIncentive.buildClaimData(parseEther('1')),
62
+ incentiveData: erc20VariableIncentive.buildClaimData(parseEther("1")),
64
63
  chainId: defaultOptions.config.chains[0].id,
65
- incentiveQuantity,
64
+ incentiveQuantity: boost.incentives.length,
66
65
  claimant,
67
66
  boostId: boost.id,
68
67
  });
@@ -81,7 +80,7 @@ describe('ERC20VariableIncentive', () => {
81
80
  ).toBe(1n);
82
81
  });
83
82
 
84
- test('cannot claim twice', async () => {
83
+ test("cannot claim twice", async () => {
85
84
  // biome-ignore lint/style/noNonNullAssertion: we know this is defined
86
85
  const referrer = accounts.at(1)!.account!;
87
86
  // biome-ignore lint/style/noNonNullAssertion: we know this is defined
@@ -101,12 +100,11 @@ describe('ERC20VariableIncentive', () => {
101
100
  });
102
101
 
103
102
  const claimant = trustedSigner.account;
104
- const incentiveQuantity = 1;
105
103
  const claimDataPayload = await boost.validator.encodeClaimData({
106
104
  signer: trustedSigner,
107
- incentiveData: erc20VariableIncentive.buildClaimData(parseEther('1')),
105
+ incentiveData: erc20VariableIncentive.buildClaimData(parseEther("1")),
108
106
  chainId: defaultOptions.config.chains[0].id,
109
- incentiveQuantity,
107
+ incentiveQuantity: boost.incentives.length,
110
108
  claimant,
111
109
  boostId: boost.id,
112
110
  });
@@ -16,6 +16,7 @@ import {
16
16
  } from '@boostxyz/evm';
17
17
  import { bytecode } from '@boostxyz/evm/artifacts/contracts/incentives/ERC20VariableIncentive.sol/ERC20VariableIncentive.json';
18
18
  import {
19
+ type Abi,
19
20
  type Address,
20
21
  type ContractEventName,
21
22
  type Hex,
@@ -86,17 +87,20 @@ export type ERC20VariableIncentiveLog<
86
87
  > = GenericLog<typeof erc20VariableIncentiveAbi, event>;
87
88
 
88
89
  /**
89
- * A modified ERC20 incentive implementation that allows claiming of variable token amounts with a spending limit
90
+ * A modified ERC20 incentive implementation that allows claiming of variable token amounts with a spending limit
90
91
  *
91
92
  * @export
92
93
  * @class ERC20VariableIncentive
93
94
  * @typedef {ERC20VariableIncentive}
94
- * @extends {DeployableTarget<ERC20VariableIncentivePayload>}
95
+ * @template [Payload=ERC20VariableIncentivePayload | undefined]
96
+ * @template {Abi} [ABI=typeof erc20VariableIncentiveAbi]
97
+ * @extends {DeployableTarget<ERC20VariableIncentivePayload, ABI>}
95
98
  */
96
- export class ERC20VariableIncentive extends DeployableTarget<
97
- ERC20VariableIncentivePayload,
98
- typeof erc20VariableIncentiveAbi
99
- > {
99
+ export class ERC20VariableIncentive<
100
+ Payload = ERC20VariableIncentivePayload | undefined,
101
+ ABI extends Abi = typeof erc20VariableIncentiveAbi,
102
+ > extends DeployableTarget<Payload, ABI> {
103
+ //@ts-expect-error it is instantiated correctly
100
104
  public override readonly abi = erc20VariableIncentiveAbi;
101
105
  /**
102
106
  * @inheritdoc
@@ -403,7 +407,7 @@ export class ERC20VariableIncentive extends DeployableTarget<
403
407
  * @returns {GenericDeployableParams}
404
408
  */
405
409
  public override buildParameters(
406
- _payload?: ERC20VariableIncentivePayload,
410
+ _payload?: Payload,
407
411
  _options?: DeployableOptions,
408
412
  ): GenericDeployableParams {
409
413
  const [payload, options] = this.validateDeploymentConfig(
@@ -413,7 +417,11 @@ export class ERC20VariableIncentive extends DeployableTarget<
413
417
  return {
414
418
  abi: erc20VariableIncentiveAbi,
415
419
  bytecode: bytecode as Hex,
416
- args: [prepareERC20VariableIncentivePayload(payload)],
420
+ args: [
421
+ prepareERC20VariableIncentivePayload(
422
+ payload as ERC20VariableIncentivePayload,
423
+ ),
424
+ ],
417
425
  ...this.optionallyAttachAccount(options.account),
418
426
  };
419
427
  }
@@ -4,6 +4,7 @@ import {
4
4
  ACGDAIncentive,
5
5
  AERC20Incentive,
6
6
  AERC20VariableIncentive,
7
+ // AERC20VariableCriteriaIncentive
7
8
  APointsIncentive,
8
9
  } from '@boostxyz/evm/deploys/componentInterfaces.json';
9
10
  import { readContract } from '@wagmi/core';
@@ -13,7 +14,7 @@ import { InvalidComponentInterfaceError } from '../errors';
13
14
  import { AllowListIncentive } from './AllowListIncentive';
14
15
  import { CGDAIncentive } from './CGDAIncentive';
15
16
  import { ERC20Incentive } from './ERC20Incentive';
16
- import type { ERC20VariableCriteriaIncentive } from './ERC20VariableCriteriaIncentive';
17
+ import { ERC20VariableCriteriaIncentive } from './ERC20VariableCriteriaIncentive';
17
18
  import { ERC20VariableIncentive } from './ERC20VariableIncentive';
18
19
  // import { ERC1155Incentive } from './ERC1155Incentive';
19
20
  import { PointsIncentive } from './PointsIncentive';
@@ -25,6 +26,7 @@ export {
25
26
  ERC20Incentive,
26
27
  PointsIncentive,
27
28
  ERC20VariableIncentive,
29
+ ERC20VariableCriteriaIncentive,
28
30
  };
29
31
 
30
32
  /**
@@ -54,6 +56,7 @@ export const IncentiveByComponentInterface = {
54
56
  // [AERC1155Incentive as Hex]: ERC1155Incentive,
55
57
  [ACGDAIncentive as Hex]: CGDAIncentive,
56
58
  [AERC20VariableIncentive as Hex]: ERC20VariableIncentive,
59
+ // [AERC20VariableCriteriaIncentive as Hex]: ERC20VariableCriteriaIncentive
57
60
  };
58
61
 
59
62
  /**
@@ -53,12 +53,11 @@ describe("PointsIncentive", () => {
53
53
 
54
54
  const claimant = trustedSigner.account;
55
55
  const incentiveData = pad("0xdef456232173821931823712381232131391321934");
56
- const incentiveQuantity = 1;
57
56
  const claimDataPayload = await boost.validator.encodeClaimData({
58
57
  signer: trustedSigner,
59
58
  incentiveData,
60
59
  chainId: defaultOptions.config.chains[0].id,
61
- incentiveQuantity,
60
+ incentiveQuantity: boost.incentives.length,
62
61
  claimant,
63
62
  boostId: boost.id,
64
63
  });
@@ -72,7 +71,7 @@ describe("PointsIncentive", () => {
72
71
  boost.id,
73
72
  0n,
74
73
  referrer,
75
- claimDataPayload
74
+ claimDataPayload,
76
75
  );
77
76
  expect(
78
77
  await readPointsBalanceOf(defaultOptions.config, {
@@ -101,12 +100,11 @@ describe("PointsIncentive", () => {
101
100
 
102
101
  const claimant = trustedSigner.account;
103
102
  const incentiveData = pad("0xdef456232173821931823712381232131391321934");
104
- const incentiveQuantity = 1;
105
103
  const claimDataPayload = await boost.validator.encodeClaimData({
106
104
  signer: trustedSigner,
107
105
  incentiveData,
108
106
  chainId: defaultOptions.config.chains[0].id,
109
- incentiveQuantity,
107
+ incentiveQuantity: boost.incentives.length,
110
108
  claimant,
111
109
  boostId: boost.id,
112
110
  });