@boostxyz/sdk 6.1.3 → 7.0.0-canary.1

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 (186) hide show
  1. package/README.md +1 -1
  2. package/dist/Actions/Action.cjs +1 -1
  3. package/dist/Actions/Action.js +7 -7
  4. package/dist/Actions/EventAction.cjs +1 -1
  5. package/dist/Actions/EventAction.cjs.map +1 -1
  6. package/dist/Actions/EventAction.d.ts +10 -0
  7. package/dist/Actions/EventAction.d.ts.map +1 -1
  8. package/dist/Actions/EventAction.js +77 -76
  9. package/dist/Actions/EventAction.js.map +1 -1
  10. package/dist/AllowLists/AllowList.cjs +1 -1
  11. package/dist/AllowLists/AllowList.js +5 -5
  12. package/dist/AllowLists/SimpleAllowList.cjs +1 -1
  13. package/dist/AllowLists/SimpleAllowList.cjs.map +1 -1
  14. package/dist/AllowLists/SimpleAllowList.js +17 -17
  15. package/dist/AllowLists/SimpleAllowList.js.map +1 -1
  16. package/dist/AllowLists/SimpleDenyList.cjs +1 -1
  17. package/dist/AllowLists/SimpleDenyList.js +3 -3
  18. package/dist/Auth/PassthroughAuth.cjs +1 -1
  19. package/dist/Auth/PassthroughAuth.js +1 -1
  20. package/dist/BoostCore.cjs +2 -2
  21. package/dist/BoostCore.cjs.map +1 -1
  22. package/dist/BoostCore.d.ts +1894 -267
  23. package/dist/BoostCore.d.ts.map +1 -1
  24. package/dist/BoostCore.js +831 -520
  25. package/dist/BoostCore.js.map +1 -1
  26. package/dist/BoostRegistry.cjs +1 -1
  27. package/dist/BoostRegistry.js +48 -48
  28. package/dist/Budget-BgGihcwx.js +1124 -0
  29. package/dist/Budget-BgGihcwx.js.map +1 -0
  30. package/dist/Budget-DYlTLLwg.cjs +2 -0
  31. package/dist/Budget-DYlTLLwg.cjs.map +1 -0
  32. package/dist/Budgets/Budget.cjs +1 -1
  33. package/dist/Budgets/Budget.d.ts +5 -4
  34. package/dist/Budgets/Budget.d.ts.map +1 -1
  35. package/dist/Budgets/Budget.js +9 -6
  36. package/dist/Budgets/ManagedBudget.cjs +1 -1
  37. package/dist/Budgets/ManagedBudget.cjs.map +1 -1
  38. package/dist/Budgets/ManagedBudget.d.ts +4 -0
  39. package/dist/Budgets/ManagedBudget.d.ts.map +1 -1
  40. package/dist/Budgets/ManagedBudget.js +22 -22
  41. package/dist/Budgets/ManagedBudgetWithFees.d.ts +4 -0
  42. package/dist/Budgets/ManagedBudgetWithFees.d.ts.map +1 -1
  43. package/dist/Budgets/ManagedBudgetWithFeesV2.d.ts +4 -0
  44. package/dist/Budgets/ManagedBudgetWithFeesV2.d.ts.map +1 -1
  45. package/dist/Budgets/TransparentBudget.d.ts +944 -0
  46. package/dist/Budgets/TransparentBudget.d.ts.map +1 -0
  47. package/dist/Budgets/VestingBudget.d.ts +4 -0
  48. package/dist/Budgets/VestingBudget.d.ts.map +1 -1
  49. package/dist/Deployable/Deployable.cjs.map +1 -1
  50. package/dist/Deployable/Deployable.d.ts +1 -1
  51. package/dist/Deployable/Deployable.d.ts.map +1 -1
  52. package/dist/Deployable/Deployable.js.map +1 -1
  53. package/dist/Deployable/DeployableTarget.cjs +1 -1
  54. package/dist/Deployable/DeployableTarget.js +1 -1
  55. package/dist/Deployable/DeployableTargetWithRBAC.cjs +1 -1
  56. package/dist/Deployable/DeployableTargetWithRBAC.js +20 -20
  57. package/dist/Incentive-BDqkFt0J.cjs +2 -0
  58. package/dist/Incentive-BDqkFt0J.cjs.map +1 -0
  59. package/dist/Incentive-DPOADY1f.js +449 -0
  60. package/dist/Incentive-DPOADY1f.js.map +1 -0
  61. package/dist/Incentives/AllowListIncentive.cjs +1 -1
  62. package/dist/Incentives/AllowListIncentive.cjs.map +1 -1
  63. package/dist/Incentives/AllowListIncentive.js +14 -14
  64. package/dist/Incentives/AllowListIncentive.js.map +1 -1
  65. package/dist/Incentives/CGDAIncentive.cjs +1 -1
  66. package/dist/Incentives/CGDAIncentive.cjs.map +1 -1
  67. package/dist/Incentives/CGDAIncentive.js +11 -11
  68. package/dist/Incentives/CGDAIncentive.js.map +1 -1
  69. package/dist/Incentives/ERC20Incentive.cjs +1 -1
  70. package/dist/Incentives/ERC20Incentive.cjs.map +1 -1
  71. package/dist/Incentives/ERC20Incentive.js +14 -14
  72. package/dist/Incentives/ERC20Incentive.js.map +1 -1
  73. package/dist/Incentives/ERC20PeggedIncentive.d.ts +1 -1
  74. package/dist/Incentives/ERC20PeggedVariableCriteriaIncentive.cjs +2 -0
  75. package/dist/Incentives/ERC20PeggedVariableCriteriaIncentive.cjs.map +1 -0
  76. package/dist/Incentives/ERC20PeggedVariableCriteriaIncentive.d.ts +3 -1
  77. package/dist/Incentives/ERC20PeggedVariableCriteriaIncentive.d.ts.map +1 -1
  78. package/dist/Incentives/ERC20PeggedVariableCriteriaIncentive.js +604 -0
  79. package/dist/Incentives/ERC20PeggedVariableCriteriaIncentive.js.map +1 -0
  80. package/dist/Incentives/ERC20PeggedVariableCriteriaIncentiveV2.cjs +2 -0
  81. package/dist/Incentives/ERC20PeggedVariableCriteriaIncentiveV2.cjs.map +1 -0
  82. package/dist/Incentives/ERC20PeggedVariableCriteriaIncentiveV2.d.ts +1103 -0
  83. package/dist/Incentives/ERC20PeggedVariableCriteriaIncentiveV2.d.ts.map +1 -0
  84. package/dist/Incentives/ERC20PeggedVariableCriteriaIncentiveV2.js +625 -0
  85. package/dist/Incentives/ERC20PeggedVariableCriteriaIncentiveV2.js.map +1 -0
  86. package/dist/Incentives/ERC20VariableCriteriaIncentive.cjs +1 -1
  87. package/dist/Incentives/ERC20VariableCriteriaIncentive.cjs.map +1 -1
  88. package/dist/Incentives/ERC20VariableCriteriaIncentive.d.ts +11 -1
  89. package/dist/Incentives/ERC20VariableCriteriaIncentive.d.ts.map +1 -1
  90. package/dist/Incentives/ERC20VariableCriteriaIncentive.js +112 -80
  91. package/dist/Incentives/ERC20VariableCriteriaIncentive.js.map +1 -1
  92. package/dist/Incentives/ERC20VariableCriteriaIncentiveV2.cjs +2 -0
  93. package/dist/Incentives/ERC20VariableCriteriaIncentiveV2.cjs.map +1 -0
  94. package/dist/Incentives/ERC20VariableCriteriaIncentiveV2.d.ts +903 -0
  95. package/dist/Incentives/ERC20VariableCriteriaIncentiveV2.d.ts.map +1 -0
  96. package/dist/Incentives/ERC20VariableCriteriaIncentiveV2.js +242 -0
  97. package/dist/Incentives/ERC20VariableCriteriaIncentiveV2.js.map +1 -0
  98. package/dist/Incentives/ERC20VariableIncentive.cjs +1 -1
  99. package/dist/Incentives/ERC20VariableIncentive.cjs.map +1 -1
  100. package/dist/Incentives/ERC20VariableIncentive.d.ts +3 -3
  101. package/dist/Incentives/ERC20VariableIncentive.d.ts.map +1 -1
  102. package/dist/Incentives/ERC20VariableIncentive.js +22 -22
  103. package/dist/Incentives/ERC20VariableIncentive.js.map +1 -1
  104. package/dist/Incentives/Incentive.cjs +1 -1
  105. package/dist/Incentives/Incentive.d.ts +8 -6
  106. package/dist/Incentives/Incentive.d.ts.map +1 -1
  107. package/dist/Incentives/Incentive.js +19 -14
  108. package/dist/Incentives/Incentive.js.map +1 -1
  109. package/dist/Incentives/PointsIncentive.cjs +1 -1
  110. package/dist/Incentives/PointsIncentive.cjs.map +1 -1
  111. package/dist/Incentives/PointsIncentive.js +9 -9
  112. package/dist/Incentives/PointsIncentive.js.map +1 -1
  113. package/dist/SimpleDenyList-B_AcmgYq.cjs +2 -0
  114. package/dist/{SimpleDenyList-DgjVf7FK.cjs.map → SimpleDenyList-B_AcmgYq.cjs.map} +1 -1
  115. package/dist/SimpleDenyList-BbDLzRw7.js +133 -0
  116. package/dist/{SimpleDenyList-BKfPoTo1.js.map → SimpleDenyList-BbDLzRw7.js.map} +1 -1
  117. package/dist/Validators/LimitedSignerValidator.cjs +1 -1
  118. package/dist/Validators/LimitedSignerValidator.cjs.map +1 -1
  119. package/dist/Validators/LimitedSignerValidator.js +13 -13
  120. package/dist/Validators/LimitedSignerValidator.js.map +1 -1
  121. package/dist/Validators/SignerValidator.cjs +1 -1
  122. package/dist/Validators/SignerValidator.cjs.map +1 -1
  123. package/dist/Validators/SignerValidator.js +52 -52
  124. package/dist/Validators/SignerValidator.js.map +1 -1
  125. package/dist/Validators/Validator.cjs +1 -1
  126. package/dist/Validators/Validator.js +2 -2
  127. package/dist/componentInterfaces-C5ig8mCK.cjs +2 -0
  128. package/dist/componentInterfaces-C5ig8mCK.cjs.map +1 -0
  129. package/dist/componentInterfaces-Ddus5rIA.js +23 -0
  130. package/dist/componentInterfaces-Ddus5rIA.js.map +1 -0
  131. package/dist/deployments-C17nvui-.cjs +2 -0
  132. package/dist/deployments-C17nvui-.cjs.map +1 -0
  133. package/dist/deployments-CH4Xmkbv.js +132 -0
  134. package/dist/{deployments-W_LUj833.js.map → deployments-CH4Xmkbv.js.map} +1 -1
  135. package/dist/deployments.json +63 -48
  136. package/dist/{generated-CElkFqkY.js → generated-CINzoGbl.js} +2611 -955
  137. package/dist/generated-CINzoGbl.js.map +1 -0
  138. package/dist/generated-C_JEoLDO.cjs +3 -0
  139. package/dist/generated-C_JEoLDO.cjs.map +1 -0
  140. package/dist/index.cjs +1 -1
  141. package/dist/index.d.ts +3 -0
  142. package/dist/index.d.ts.map +1 -1
  143. package/dist/index.js +167 -154
  144. package/dist/index.js.map +1 -1
  145. package/dist/utils.cjs.map +1 -1
  146. package/dist/utils.js.map +1 -1
  147. package/package.json +20 -2
  148. package/src/Actions/EventAction.ts +11 -0
  149. package/src/BoostCore.test.ts +14 -9
  150. package/src/BoostCore.ts +428 -26
  151. package/src/Budgets/Budget.ts +8 -1
  152. package/src/Budgets/TransparentBudget.test.ts +70 -0
  153. package/src/Budgets/TransparentBudget.ts +334 -0
  154. package/src/Deployable/Deployable.ts +1 -1
  155. package/src/Incentives/ERC20PeggedIncentive.ts +1 -1
  156. package/src/Incentives/ERC20PeggedVariableCriteriaIncentive.ts +3 -1
  157. package/src/Incentives/{ERC20PeggedVariableCriteriaIncentive.test.ts → ERC20PeggedVariableCriteriaIncentiveV2.test.ts} +20 -16
  158. package/src/Incentives/ERC20PeggedVariableCriteriaIncentiveV2.ts +872 -0
  159. package/src/Incentives/ERC20VariableCriteriaIncentive.ts +50 -1
  160. package/src/Incentives/{ERC20VariableCriteriaIncentive.test.ts → ERC20VariableCriteriaIncentiveV2.test.ts} +24 -19
  161. package/src/Incentives/ERC20VariableCriteriaIncentiveV2.ts +447 -0
  162. package/src/Incentives/ERC20VariableIncentive.ts +4 -2
  163. package/src/Incentives/Incentive.ts +13 -2
  164. package/src/index.test.ts +2 -2
  165. package/src/index.ts +3 -0
  166. package/src/utils.ts +1 -1
  167. package/dist/Budget-BjfL8dVX.cjs +0 -2
  168. package/dist/Budget-BjfL8dVX.cjs.map +0 -1
  169. package/dist/Budget-DD7IPuDx.js +0 -922
  170. package/dist/Budget-DD7IPuDx.js.map +0 -1
  171. package/dist/Incentive-V1RjH38L.js +0 -1036
  172. package/dist/Incentive-V1RjH38L.js.map +0 -1
  173. package/dist/Incentive-gVTfsnMB.cjs +0 -2
  174. package/dist/Incentive-gVTfsnMB.cjs.map +0 -1
  175. package/dist/SimpleDenyList-BKfPoTo1.js +0 -133
  176. package/dist/SimpleDenyList-DgjVf7FK.cjs +0 -2
  177. package/dist/componentInterfaces-CA1UIqWL.js +0 -20
  178. package/dist/componentInterfaces-CA1UIqWL.js.map +0 -1
  179. package/dist/componentInterfaces-aBgBbB7r.cjs +0 -2
  180. package/dist/componentInterfaces-aBgBbB7r.cjs.map +0 -1
  181. package/dist/deployments-CwTZr-cK.cjs +0 -2
  182. package/dist/deployments-CwTZr-cK.cjs.map +0 -1
  183. package/dist/deployments-W_LUj833.js +0 -117
  184. package/dist/generated-BPiHi7W2.cjs +0 -3
  185. package/dist/generated-BPiHi7W2.cjs.map +0 -1
  186. package/dist/generated-CElkFqkY.js.map +0 -1
@@ -10,8 +10,10 @@ import {
10
10
  type AbiFunction,
11
11
  type Address,
12
12
  type Hex,
13
+ decodeAbiParameters,
13
14
  decodeFunctionData,
14
15
  encodeAbiParameters,
16
+ parseEther,
15
17
  parseEventLogs,
16
18
  zeroAddress,
17
19
  zeroHash,
@@ -106,13 +108,15 @@ export interface GetIncentiveScalarParams {
106
108
  * Extended ERC20 Variable Criteria Incentive class that fetches incentive criteria and scalar
107
109
  *
108
110
  * @export
111
+ * @deprecated Please use only v2 implementations
109
112
  * @class ERC20VariableCriteriaIncentive
110
113
  * @typedef {ERC20VariableCriteriaIncentive}
111
114
  * @extends {ERC20VariableIncentive<ERC20VariableCriteriaIncentivePayload, typeof erc20VariableCriteriaIncentiveAbi>}
112
115
  */
113
116
  export class ERC20VariableCriteriaIncentive extends ERC20VariableIncentive<
114
117
  ERC20VariableCriteriaIncentivePayload,
115
- typeof erc20VariableCriteriaIncentiveAbi
118
+ typeof erc20VariableCriteriaIncentiveAbi,
119
+ Promise<bigint>
116
120
  > {
117
121
  //@ts-expect-error instantiated correctly
118
122
  public override readonly abi = erc20VariableCriteriaIncentiveAbi;
@@ -158,6 +162,51 @@ export class ERC20VariableCriteriaIncentive extends ERC20VariableIncentive<
158
162
  }
159
163
  }
160
164
 
165
+ /**
166
+ * Decodes claim data for the ERC20VariableCriteriaIncentive, returning the claim amount.
167
+ * Useful when deriving amount claimed from logs.
168
+ *
169
+ * @public
170
+ * @param {Hex} claimData
171
+ * @returns {Promise<bigint>} Returns the reward amount from a claim data payload
172
+ */
173
+ public override async decodeClaimData(claimData: Hex) {
174
+ const boostClaimData = decodeAbiParameters(
175
+ [
176
+ {
177
+ type: 'tuple',
178
+ name: 'BoostClaimData',
179
+ components: [
180
+ { type: 'bytes', name: 'validatorData' },
181
+ { type: 'bytes', name: 'incentiveData' },
182
+ ],
183
+ },
184
+ ],
185
+ claimData,
186
+ );
187
+ const signedAmount = decodeAbiParameters(
188
+ [{ type: 'uint256' }],
189
+ boostClaimData[0].incentiveData,
190
+ )[0];
191
+ let claimAmount = signedAmount;
192
+ const [reward, maxReward] = await Promise.all([
193
+ this.reward(),
194
+ this.getMaxReward(),
195
+ ]);
196
+
197
+ if (reward === 0n) {
198
+ return claimAmount;
199
+ } else {
200
+ claimAmount = (reward * signedAmount) / parseEther('1');
201
+ }
202
+
203
+ if (maxReward !== 0n && claimAmount > maxReward) {
204
+ claimAmount = maxReward;
205
+ }
206
+
207
+ return claimAmount;
208
+ }
209
+
161
210
  /**
162
211
  * Fetches the IncentiveCriteria struct from the contract
163
212
  *
@@ -23,14 +23,14 @@ import {
23
23
  zeroHash,
24
24
  } from "viem";
25
25
  import { beforeAll, beforeEach, describe, expect, test } from "vitest";
26
- import { SignatureType } from "../Actions/EventAction";
26
+ import { SignatureType, ValueType } from "../Actions/EventAction";
27
27
  import type { Boost } from "../Boost";
28
28
  import {
29
- type ERC20VariableCriteriaIncentive,
30
- type ERC20VariableCriteriaIncentivePayload,
31
- type IncentiveCriteria,
32
- gasRebateIncentiveCriteria,
33
- } from "./ERC20VariableCriteriaIncentive";
29
+ type ERC20VariableCriteriaIncentiveV2,
30
+ type ERC20VariableCriteriaIncentiveV2Payload,
31
+ type IncentiveCriteriaV2,
32
+ gasRebateIncentiveCriteriaV2,
33
+ } from "./ERC20VariableCriteriaIncentiveV2";
34
34
  import { allKnownSignatures } from "@boostxyz/test/allKnownSignatures";
35
35
 
36
36
  /**
@@ -41,12 +41,13 @@ import { allKnownSignatures } from "@boostxyz/test/allKnownSignatures";
41
41
  */
42
42
  export function basicErc721TransferScalarCriteria(
43
43
  erc721: MockERC721,
44
- ): IncentiveCriteria {
44
+ ): IncentiveCriteriaV2 {
45
45
  return {
46
46
  criteriaType: SignatureType.FUNC,
47
47
  signature: funcSelectors["transferFrom(address,address,uint256)"] as Hex, // Function selector for mint
48
48
  fieldIndex: 2, // Field where the scalar value resides
49
49
  targetContract: erc721.assertValidAddress(),
50
+ valueType: ValueType.WAD,
50
51
  };
51
52
  }
52
53
 
@@ -58,7 +59,7 @@ export function basicErc721TransferScalarCriteria(
58
59
  */
59
60
  export function basicErc721MintScalarCriteria(
60
61
  erc721: MockERC721,
61
- ): IncentiveCriteria {
62
+ ): IncentiveCriteriaV2 {
62
63
  return {
63
64
  criteriaType: SignatureType.EVENT,
64
65
  signature: eventSelectors[
@@ -66,6 +67,7 @@ export function basicErc721MintScalarCriteria(
66
67
  ] as Hex, // Function selector for mint
67
68
  fieldIndex: 2, // Field where the scalar value resides
68
69
  targetContract: erc721.assertValidAddress(),
70
+ valueType: ValueType.WAD,
69
71
  };
70
72
  }
71
73
 
@@ -77,7 +79,7 @@ export function basicErc721MintScalarCriteria(
77
79
  */
78
80
  export function basicErc721TransferScalarPayload(
79
81
  erc721: MockERC721,
80
- ): ERC20VariableCriteriaIncentivePayload {
82
+ ): ERC20VariableCriteriaIncentiveV2Payload {
81
83
  return {
82
84
  asset: erc721.assertValidAddress(),
83
85
  reward: 1n,
@@ -90,11 +92,11 @@ export function basicErc721TransferScalarPayload(
90
92
  let fixtures: Fixtures,
91
93
  erc20: MockERC20,
92
94
  erc721: MockERC721,
93
- erc20Incentive: ERC20VariableCriteriaIncentive,
95
+ erc20Incentive: ERC20VariableCriteriaIncentiveV2,
94
96
  budgets: BudgetFixtures,
95
97
  boost: Boost;
96
98
 
97
- describe("ERC20VariableCriteriaIncentive", () => {
99
+ describe("ERC20VariableCriteriaIncentiveV2", () => {
98
100
  beforeAll(async () => {
99
101
  fixtures = await loadFixture(deployFixtures(defaultOptions));
100
102
  });
@@ -103,7 +105,7 @@ describe("ERC20VariableCriteriaIncentive", () => {
103
105
  budgets = await loadFixture(fundBudget(defaultOptions, fixtures));
104
106
  erc20 = await loadFixture(fundErc20(defaultOptions));
105
107
  erc721 = await loadFixture(fundErc721(defaultOptions));
106
- erc20Incentive = fixtures.core.ERC20VariableCriteriaIncentive({
108
+ erc20Incentive = fixtures.core.ERC20VariableCriteriaIncentiveV2({
107
109
  asset: budgets.erc20.assertValidAddress(),
108
110
  reward: 1n,
109
111
  limit: 1n,
@@ -119,13 +121,14 @@ describe("ERC20VariableCriteriaIncentive", () => {
119
121
 
120
122
  describe("getIncentiveCriteria", () => {
121
123
  test("should fetch incentive criteria successfully", async () => {
122
- const incentive = boost.incentives[0] as ERC20VariableCriteriaIncentive;
124
+ const incentive = boost.incentives[0] as ERC20VariableCriteriaIncentiveV2;
123
125
  const criteria = await incentive.getIncentiveCriteria();
124
126
  expect(criteria).toMatchObject({
125
127
  criteriaType: SignatureType.FUNC,
126
128
  signature: expect.any(String),
127
129
  fieldIndex: expect.any(Number),
128
130
  targetContract: expect.any(String),
131
+ valueType: expect.any(Number),
129
132
  });
130
133
  });
131
134
  });
@@ -149,7 +152,7 @@ describe("ERC20VariableCriteriaIncentive", () => {
149
152
  });
150
153
 
151
154
  test("should return a valid scalar for event-based criteria", async () => {
152
- erc20Incentive = fixtures.core.ERC20VariableCriteriaIncentive({
155
+ erc20Incentive = fixtures.core.ERC20VariableCriteriaIncentiveV2({
153
156
  asset: budgets.erc20.assertValidAddress(),
154
157
  reward: 1n,
155
158
  limit: 1n,
@@ -176,11 +179,11 @@ describe("ERC20VariableCriteriaIncentive", () => {
176
179
  expect(scalar).toBe(1n);
177
180
  });
178
181
 
179
- test("gasRebateIncentiveCriteria generates correct incentive criteria", async () => {
182
+ test("gasRebateIncentiveCriteriaV2 generates correct incentive criteria", async () => {
180
183
  // Ensure that the gasRebateIncentiveCriteria returns the correct structure
181
- const gasRebateCriteria = gasRebateIncentiveCriteria();
184
+ const gasRebateCriteria = gasRebateIncentiveCriteriaV2();
182
185
 
183
- erc20Incentive = fixtures.core.ERC20VariableCriteriaIncentive({
186
+ erc20Incentive = fixtures.core.ERC20VariableCriteriaIncentiveV2({
184
187
  asset: budgets.erc20.assertValidAddress(),
185
188
  reward: 1n,
186
189
  limit: 1n,
@@ -194,6 +197,7 @@ describe("ERC20VariableCriteriaIncentive", () => {
194
197
  signature: zeroHash,
195
198
  fieldIndex: 255,
196
199
  targetContract: zeroAddress,
200
+ valueType: ValueType.WAD,
197
201
  });
198
202
 
199
203
  boost = await freshBoost(fixtures, {
@@ -203,12 +207,13 @@ describe("ERC20VariableCriteriaIncentive", () => {
203
207
 
204
208
  // Validate that the deployed incentive has the correct criteria set up
205
209
  const deployedIncentive = (await boost
206
- .incentives[0]) as ERC20VariableCriteriaIncentive;
210
+ .incentives[0]) as ERC20VariableCriteriaIncentiveV2;
207
211
  const deployedCriteria = await deployedIncentive.getIncentiveCriteria();
208
212
  expect(deployedCriteria.criteriaType).toBe(SignatureType.EVENT);
209
213
  expect(deployedCriteria.signature).toBe(zeroHash);
210
214
  expect(deployedCriteria.fieldIndex).toBe(255);
211
215
  expect(deployedCriteria.targetContract).toBe(zeroAddress);
216
+ expect(deployedCriteria.valueType).toBe(ValueType.WAD);
212
217
  });
213
218
 
214
219
  test("should throw NoMatchingLogsError for event criteria with no matching logs", async () => {
@@ -245,7 +250,7 @@ describe("ERC20VariableCriteriaIncentive", () => {
245
250
 
246
251
  test("can properly encode a uint256", () => {
247
252
  //@ts-ignore
248
- const incentive = fixtures.core.ERC20VariableCriteriaIncentive();
253
+ const incentive = fixtures.core.ERC20VariableCriteriaIncentiveV2();
249
254
  expect(incentive.buildClawbackData(1n)).toBe(
250
255
  "0x0000000000000000000000000000000000000000000000000000000000000001",
251
256
  );
@@ -0,0 +1,447 @@
1
+ import {
2
+ erc20VariableCriteriaIncentiveV2Abi,
3
+ readErc20VariableCriteriaIncentiveV2GetIncentiveCriteria,
4
+ readErc20VariableCriteriaIncentiveV2GetMaxReward,
5
+ } from '@boostxyz/evm';
6
+ import { bytecode } from '@boostxyz/evm/artifacts/contracts/incentives/ERC20VariableCriteriaIncentiveV2.sol/ERC20VariableCriteriaIncentiveV2.json';
7
+ import { getTransaction, getTransactionReceipt } from '@wagmi/core';
8
+ import {
9
+ type AbiEvent,
10
+ type AbiFunction,
11
+ type Address,
12
+ type Hex,
13
+ decodeAbiParameters,
14
+ decodeFunctionData,
15
+ encodeAbiParameters,
16
+ parseEther,
17
+ parseEventLogs,
18
+ zeroAddress,
19
+ zeroHash,
20
+ } from 'viem';
21
+ import { ERC20VariableCriteriaIncentiveV2 as ERC20VariableCriteriaIncentiveV2Bases } from '../../dist/deployments.json';
22
+ import { SignatureType, ValueType } from '../Actions/EventAction';
23
+ import type {
24
+ DeployableOptions,
25
+ GenericDeployableParams,
26
+ } from '../Deployable/Deployable';
27
+ import {
28
+ DecodedArgsError,
29
+ IncentiveCriteriaNotFoundError,
30
+ InvalidCriteriaTypeError,
31
+ NoMatchingLogsError,
32
+ } from '../errors';
33
+ import { CheatCodes, type ReadParams } from '../utils';
34
+ import { ERC20VariableIncentive } from './ERC20VariableIncentive';
35
+
36
+ export { erc20VariableCriteriaIncentiveV2Abi };
37
+
38
+ export interface ERC20VariableCriteriaIncentiveV2Payload {
39
+ /**
40
+ * The address of the incentivized asset.
41
+ *
42
+ * @type {Address}
43
+ */
44
+ asset: Address;
45
+ /**
46
+ * The amount of the asset to distribute as reward.
47
+ *
48
+ * @type {bigint}
49
+ */
50
+ reward: bigint;
51
+ /**
52
+ * The total spending limit of the asset that will be distributed.
53
+ *
54
+ * @type {bigint}
55
+ */
56
+ limit: bigint;
57
+ /**
58
+ * The total amount claimable in a single claim or maximum per-action reward.
59
+ *
60
+ * @type {bigint}
61
+ * @optional
62
+ */
63
+ maxReward?: bigint;
64
+ /**
65
+ * The criteria for the incentive that determines how the reward is distributed.
66
+ *
67
+ * @type {IncentiveCriteria}
68
+ */
69
+ criteria: IncentiveCriteriaV2;
70
+ }
71
+
72
+ export interface IncentiveCriteriaV2 {
73
+ /**
74
+ * The type of criteria used, either function signature or event signature.
75
+ *
76
+ * @type {SignatureType}
77
+ */
78
+ criteriaType: SignatureType;
79
+ /**
80
+ * The function or event signature used for criteria matching.
81
+ *
82
+ * @type {Hex}
83
+ */
84
+ signature: Hex;
85
+ /**
86
+ * The index of the field from where the scalar value is extracted.
87
+ *
88
+ * @type {number}
89
+ */
90
+ fieldIndex: number;
91
+ /**
92
+ * The address of the contract where the event/function is called/emitted.
93
+ *
94
+ * @type {Address}
95
+ */
96
+ targetContract: Address;
97
+ /**
98
+ * The type of value used for the scalar value (RAW or WAD).
99
+ * - RAW: Raw integer value (e.g., NFT quantity)
100
+ * - WAD: Value with 18 decimals (e.g., token amount)
101
+ *
102
+ * @type {ValueType}
103
+ */
104
+ valueType: ValueType;
105
+ }
106
+
107
+ export interface ReadIncentiveCriteriaV2Params extends ReadParams {}
108
+
109
+ export interface GetIncentiveScalarV2Params {
110
+ chainId: number;
111
+ hash: Hex;
112
+ knownSignatures: Record<Hex, AbiFunction | AbiEvent>;
113
+ }
114
+
115
+ /**
116
+ * Extended ERC20 Variable Criteria Incentive class that fetches incentive criteria and scalar
117
+ *
118
+ * @export
119
+ * @class ERC20VariableCriteriaIncentive
120
+ * @typedef {ERC20VariableCriteriaIncentiveV2}
121
+ * @extends {ERC20VariableIncentive<ERC20VariableCriteriaIncentiveV2Payload, typeof erc20VariableCriteriaIncentiveV2Abi>}
122
+ */
123
+ export class ERC20VariableCriteriaIncentiveV2 extends ERC20VariableIncentive<
124
+ ERC20VariableCriteriaIncentiveV2Payload,
125
+ typeof erc20VariableCriteriaIncentiveV2Abi,
126
+ Promise<bigint>
127
+ > {
128
+ //@ts-expect-error instantiated correctly
129
+ public override readonly abi = erc20VariableCriteriaIncentiveV2Abi;
130
+ /**
131
+ * @inheritdoc
132
+ *
133
+ * @public
134
+ * @static
135
+ * @type {Record<number, Address>}
136
+ */
137
+ public static override bases: Record<number, Address> = {
138
+ 31337: import.meta.env.VITE_ERC20_VARIABLE_CRITERIA_INCENTIVE_V2_BASE,
139
+ ...(ERC20VariableCriteriaIncentiveV2Bases as Record<number, Address>),
140
+ };
141
+
142
+ /**
143
+ *Functions from the ERC20VariableIncentive contract
144
+ */
145
+
146
+ /**
147
+ * Fetches the IncentiveCriteria struct from the contract
148
+ *
149
+ * @param {?ReadParams} [params]
150
+ * @returns {Promise<IncentiveCriteria>} Incentive criteria structure
151
+ * @throws {IncentiveCriteriaNotFoundError}
152
+ */
153
+ public async getIncentiveCriteria(
154
+ params?: ReadParams,
155
+ ): Promise<IncentiveCriteriaV2> {
156
+ try {
157
+ const criteria =
158
+ await readErc20VariableCriteriaIncentiveV2GetIncentiveCriteria(
159
+ this._config,
160
+ {
161
+ ...params,
162
+ address: this.assertValidAddress(),
163
+ },
164
+ );
165
+
166
+ return criteria;
167
+ } catch (e) {
168
+ throw new IncentiveCriteriaNotFoundError(e as Error);
169
+ }
170
+ }
171
+
172
+ /**
173
+ * Decodes claim data for the ERC20VariableCriteriaIncentiveV2, returning the claim amount.
174
+ * Useful when deriving amount claimed from logs.
175
+ *
176
+ * @public
177
+ * @param {Hex} claimData
178
+ * @returns {Promise<bigint>} Returns the reward amount from a claim data payload
179
+ */
180
+ public override async decodeClaimData(claimData: Hex) {
181
+ const boostClaimData = decodeAbiParameters(
182
+ [
183
+ {
184
+ type: 'tuple',
185
+ name: 'BoostClaimData',
186
+ components: [
187
+ { type: 'bytes', name: 'validatorData' },
188
+ { type: 'bytes', name: 'incentiveData' },
189
+ ],
190
+ },
191
+ ],
192
+ claimData,
193
+ );
194
+ const signedAmount = decodeAbiParameters(
195
+ [{ type: 'uint256' }],
196
+ boostClaimData[0].incentiveData,
197
+ )[0];
198
+ let claimAmount = signedAmount;
199
+ const [reward, maxReward] = await Promise.all([
200
+ this.reward(),
201
+ this.getMaxReward(),
202
+ ]);
203
+
204
+ if (reward === 0n) {
205
+ return claimAmount;
206
+ } else {
207
+ claimAmount = (reward * signedAmount) / parseEther('1');
208
+ }
209
+
210
+ if (maxReward !== 0n && claimAmount > maxReward) {
211
+ claimAmount = maxReward;
212
+ }
213
+
214
+ return claimAmount;
215
+ }
216
+
217
+ /**
218
+ * Fetches the IncentiveCriteria struct from the contract
219
+ *
220
+ * @param {?ReadParams} [params]
221
+ * @returns {Promise<IncentiveCriteria>} Incentive criteria structure
222
+ * @throws {IncentiveCriteriaNotFoundError}
223
+ */
224
+ public async getMaxReward(params?: ReadParams): Promise<bigint> {
225
+ const maxReward = await readErc20VariableCriteriaIncentiveV2GetMaxReward(
226
+ this._config,
227
+ {
228
+ ...params,
229
+ address: this.assertValidAddress(),
230
+ },
231
+ );
232
+
233
+ return maxReward;
234
+ }
235
+
236
+ /**
237
+ * Fetches the incentive scalar from a transaction hash
238
+ *
239
+ * @param {GetIncentiveScalarParams} params
240
+ * @param {?ReadParams} [params]
241
+ * @returns {Promise<bigint>}
242
+ * @throws {InvalidCriteriaTypeError | NoMatchingLogsError | DecodedArgsError}
243
+ */
244
+ public async getIncentiveScalar(
245
+ { chainId, hash, knownSignatures }: GetIncentiveScalarV2Params,
246
+ params?: ReadParams,
247
+ ): Promise<bigint> {
248
+ const criteria = await this.getIncentiveCriteria(params);
249
+ if (criteria.criteriaType === SignatureType.EVENT) {
250
+ const transactionReceipt = await getTransactionReceipt(this._config, {
251
+ chainId,
252
+ hash,
253
+ });
254
+ if (criteria.fieldIndex === CheatCodes.GAS_REBATE_INCENTIVE) {
255
+ const totalCost =
256
+ transactionReceipt.gasUsed * transactionReceipt.effectiveGasPrice + // Normal gas cost
257
+ (transactionReceipt.blobGasUsed ?? 0n) *
258
+ (transactionReceipt.blobGasPrice ?? 0n); // Blob gas cost - account for potential undefined values
259
+ return totalCost;
260
+ }
261
+ const logs = transactionReceipt.logs;
262
+
263
+ if (logs.length === 0) {
264
+ throw new NoMatchingLogsError(
265
+ `No logs found for event signature ${criteria.signature}`,
266
+ );
267
+ }
268
+
269
+ // Decode the event log
270
+ try {
271
+ // Decode function data
272
+ const eventAbi = knownSignatures[criteria.signature] as AbiEvent;
273
+ const decodedEvents = parseEventLogs({
274
+ abi: [eventAbi],
275
+ logs,
276
+ });
277
+ if (decodedEvents == undefined || decodedEvents.length === 0) {
278
+ throw new NoMatchingLogsError(
279
+ `No logs found for event signature ${criteria.signature}`,
280
+ );
281
+ }
282
+ const scalarValue = (decodedEvents[0]?.args as string[])[
283
+ criteria.fieldIndex
284
+ ];
285
+
286
+ if (scalarValue === undefined) {
287
+ throw new DecodedArgsError(
288
+ `Decoded argument at index ${criteria.fieldIndex} is undefined`,
289
+ );
290
+ }
291
+ return BigInt(scalarValue);
292
+ } catch (e) {
293
+ throw new DecodedArgsError(
294
+ `Failed to decode event log for signature ${criteria.signature}: ${(e as Error).message}`,
295
+ );
296
+ }
297
+ } else if (criteria.criteriaType === SignatureType.FUNC) {
298
+ // Fetch the transaction data
299
+ const transaction = await getTransaction(this._config, {
300
+ chainId,
301
+ hash,
302
+ });
303
+ try {
304
+ // Decode function data
305
+ const func = knownSignatures[criteria.signature] as AbiFunction;
306
+ const decodedFunction = decodeFunctionData({
307
+ abi: [func],
308
+ data: transaction.input,
309
+ });
310
+ const scalarValue = decodedFunction.args[criteria.fieldIndex] as string;
311
+ if (scalarValue === undefined || scalarValue === null) {
312
+ throw new DecodedArgsError(
313
+ `Decoded argument at index ${criteria.fieldIndex} is undefined`,
314
+ );
315
+ }
316
+ return BigInt(scalarValue);
317
+ } catch (e) {
318
+ throw new DecodedArgsError(
319
+ `Failed to decode function data for signature ${criteria.signature}: ${(e as Error).message}`,
320
+ );
321
+ }
322
+ } else {
323
+ throw new InvalidCriteriaTypeError(
324
+ `Invalid criteria type ${criteria.criteriaType}`,
325
+ );
326
+ }
327
+ }
328
+
329
+ /**
330
+ * @inheritdoc
331
+ *
332
+ * @public
333
+ * @param {?ERC20VariableCriteriaIncentiveV2Payload} [_payload]
334
+ * @param {?DeployableOptions} [_options]
335
+ * @returns {GenericDeployableParams}
336
+ */
337
+ public override buildParameters(
338
+ _payload?: ERC20VariableCriteriaIncentiveV2Payload,
339
+ _options?: DeployableOptions,
340
+ ): GenericDeployableParams {
341
+ const [payload, options] = this.validateDeploymentConfig(
342
+ _payload,
343
+ _options,
344
+ );
345
+ return {
346
+ abi: erc20VariableCriteriaIncentiveV2Abi,
347
+ bytecode: bytecode as Hex,
348
+ args: [prepareERC20VariableCriteriaIncentiveV2Payload(payload)],
349
+ ...this.optionallyAttachAccount(options.account),
350
+ };
351
+ }
352
+ }
353
+
354
+ /**
355
+ * Creates an IncentiveCriteria object representing a gas rebate incentive.
356
+ * This object defines a variable incentive criteria where the criteria will be the gas spent.
357
+ *
358
+ * The criteria uses a signatureType of EVENT, with a special `fieldIndex` of 255 (using CheatCodes enum), which indicates
359
+ * that the entire gas cost of the transaction will be used as the scalar value. If you don't want to
360
+ * rebate the entire gas cost, you can use a reward value on the incentive..
361
+ *
362
+ * - `criteriaType`: EVENT, indicating it's based on event logs.
363
+ * - `signature`: A zeroed signature (0x0000...0000), matching any event.
364
+ * - `fieldIndex`: 255, indicating the use of transaction gas cost using CheatCodes enum.
365
+ * - `targetContract`: A zeroed address (0x0000...0000), applicable to any contract.
366
+ *
367
+ * @returns {IncentiveCriteria} Returns an IncentiveCriteria object for a gas rebate.
368
+ *
369
+ * @example
370
+ * const incentive = gasRebateIncentiveCriteria();
371
+ * const actionPayload = {
372
+ * criteria: incentive,
373
+ * asset: "0xAssetAddress",
374
+ * reward: 0, // Set to zero to rebate the entire gas cost
375
+ * limit: BigInt(1000) // This is the total spend limit for the incentive
376
+ * };
377
+ * deployIncentive(actionPayload);
378
+ */
379
+ export function gasRebateIncentiveCriteriaV2(): IncentiveCriteriaV2 {
380
+ return {
381
+ criteriaType: SignatureType.EVENT,
382
+ signature: zeroHash,
383
+ fieldIndex: CheatCodes.GAS_REBATE_INCENTIVE,
384
+ targetContract: zeroAddress,
385
+ valueType: ValueType.WAD,
386
+ };
387
+ }
388
+
389
+ /**
390
+ *
391
+ *
392
+ * @param {InitPayloadExtended} param0
393
+ * @param {Address} param0.asset - The address of the ERC20 asset to incentivize.
394
+ * @param {bigint} param0.reward - The reward amount to distribute per action.
395
+ * @param {bigint} param0.limit - The total limit of the asset distribution.
396
+ * @param {bigint} param0.maxReward - The maximum value claimable from a single completion.
397
+ * @param {IncentiveCriteria} param0.criteria - The incentive criteria for reward distribution.
398
+ * @returns {Hex}
399
+ */
400
+ export function prepareERC20VariableCriteriaIncentiveV2Payload({
401
+ asset,
402
+ reward,
403
+ limit,
404
+ maxReward = 0n,
405
+ criteria,
406
+ }: ERC20VariableCriteriaIncentiveV2Payload) {
407
+ return encodeAbiParameters(
408
+ [
409
+ {
410
+ type: 'tuple',
411
+ name: 'initPayloadExtended',
412
+ components: [
413
+ { type: 'address', name: 'asset' },
414
+ { type: 'uint256', name: 'reward' },
415
+ { type: 'uint256', name: 'limit' },
416
+ { type: 'uint256', name: 'maxReward' },
417
+ {
418
+ type: 'tuple',
419
+ name: 'criteria',
420
+ components: [
421
+ { type: 'uint8', name: 'criteriaType' },
422
+ { type: 'bytes32', name: 'signature' },
423
+ { type: 'uint8', name: 'fieldIndex' },
424
+ { type: 'address', name: 'targetContract' },
425
+ { type: 'uint8', name: 'valueType' },
426
+ ],
427
+ },
428
+ ],
429
+ },
430
+ ],
431
+ [
432
+ {
433
+ asset: asset,
434
+ reward: reward,
435
+ limit: limit,
436
+ maxReward: maxReward,
437
+ criteria: {
438
+ criteriaType: criteria.criteriaType,
439
+ signature: criteria.signature,
440
+ fieldIndex: criteria.fieldIndex,
441
+ targetContract: criteria.targetContract,
442
+ valueType: criteria.valueType,
443
+ },
444
+ },
445
+ ],
446
+ );
447
+ }
@@ -101,6 +101,7 @@ export type ERC20VariableIncentiveLog<
101
101
  export class ERC20VariableIncentive<
102
102
  Payload = ERC20VariableIncentivePayload | undefined,
103
103
  ABI extends Abi = typeof erc20VariableIncentiveAbi,
104
+ DecodedClaimPayload = bigint,
104
105
  > extends DeployableTarget<Payload, ABI> {
105
106
  //@ts-expect-error it is instantiated correctly
106
107
  public override readonly abi = erc20VariableIncentiveAbi;
@@ -434,9 +435,10 @@ export class ERC20VariableIncentive<
434
435
  *
435
436
  * @public
436
437
  * @param {Hex} claimData
437
- * @returns {BigInt} Returns the reward amount from a claim data payload
438
+ * @returns {bigint} Returns the reward amount from a claim data payload
438
439
  */
439
- public decodeClaimData(data: Hex) {
440
+ public decodeClaimData(data: Hex): DecodedClaimPayload {
441
+ //@ts-expect-error making this generic to prevent major version
440
442
  return BigInt(decodeAbiParameters([{ type: 'uint256' }], data)[0]);
441
443
  }
442
444