@boostxyz/sdk 5.3.1 → 6.0.0
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.
- package/dist/Actions/Action.cjs +1 -1
- package/dist/Actions/Action.js +3 -3
- package/dist/Actions/EventAction.cjs +1 -1
- package/dist/Actions/EventAction.cjs.map +1 -1
- package/dist/Actions/EventAction.d.ts +13 -3
- package/dist/Actions/EventAction.d.ts.map +1 -1
- package/dist/Actions/EventAction.js +216 -193
- package/dist/Actions/EventAction.js.map +1 -1
- package/dist/AllowLists/AllowList.cjs +1 -1
- package/dist/AllowLists/AllowList.js +2 -2
- package/dist/AllowLists/SimpleAllowList.cjs +1 -1
- package/dist/AllowLists/SimpleAllowList.cjs.map +1 -1
- package/dist/AllowLists/SimpleAllowList.js +24 -24
- package/dist/AllowLists/SimpleAllowList.js.map +1 -1
- package/dist/AllowLists/SimpleDenyList.cjs +1 -1
- package/dist/AllowLists/SimpleDenyList.js +3 -3
- package/dist/Auth/PassthroughAuth.cjs +1 -1
- package/dist/Auth/PassthroughAuth.cjs.map +1 -1
- package/dist/Auth/PassthroughAuth.js +14 -14
- package/dist/Boost.cjs.map +1 -1
- package/dist/Boost.js.map +1 -1
- package/dist/BoostCore.cjs +2 -2
- package/dist/BoostCore.cjs.map +1 -1
- package/dist/BoostCore.d.ts +247 -0
- package/dist/BoostCore.d.ts.map +1 -1
- package/dist/BoostCore.js +421 -259
- package/dist/BoostCore.js.map +1 -1
- package/dist/BoostRegistry.cjs +1 -1
- package/dist/BoostRegistry.cjs.map +1 -1
- package/dist/BoostRegistry.js +43 -43
- package/dist/BoostRegistry.js.map +1 -1
- package/dist/Budget-DMbfdTom.cjs +2 -0
- package/dist/{Budget-AoNx7uFd.cjs.map → Budget-DMbfdTom.cjs.map} +1 -1
- package/dist/Budget-DO6sGTIR.js +463 -0
- package/dist/{Budget-DYIV9iNK.js.map → Budget-DO6sGTIR.js.map} +1 -1
- package/dist/Budgets/Budget.cjs +1 -1
- package/dist/Budgets/Budget.js +2 -2
- package/dist/Budgets/ManagedBudget.cjs +1 -1
- package/dist/Budgets/ManagedBudget.cjs.map +1 -1
- package/dist/Budgets/ManagedBudget.js +53 -53
- package/dist/Budgets/ManagedBudgetWithFees.d.ts +26 -0
- package/dist/Budgets/ManagedBudgetWithFees.d.ts.map +1 -1
- package/dist/Deployable/DeployableTarget.cjs +1 -1
- package/dist/Deployable/DeployableTarget.js +1 -1
- package/dist/Deployable/DeployableTargetWithRBAC.cjs +1 -1
- package/dist/Deployable/DeployableTargetWithRBAC.js +15 -15
- package/dist/Incentive-Boviez4z.js +1036 -0
- package/dist/Incentive-Boviez4z.js.map +1 -0
- package/dist/Incentive-wM4zizTH.cjs +2 -0
- package/dist/Incentive-wM4zizTH.cjs.map +1 -0
- package/dist/Incentives/AllowListIncentive.cjs +1 -1
- package/dist/Incentives/AllowListIncentive.cjs.map +1 -1
- package/dist/Incentives/AllowListIncentive.d.ts +9 -1
- package/dist/Incentives/AllowListIncentive.d.ts.map +1 -1
- package/dist/Incentives/AllowListIncentive.js +64 -47
- package/dist/Incentives/AllowListIncentive.js.map +1 -1
- package/dist/Incentives/CGDAIncentive.cjs +1 -1
- package/dist/Incentives/CGDAIncentive.cjs.map +1 -1
- package/dist/Incentives/CGDAIncentive.d.ts +12 -1
- package/dist/Incentives/CGDAIncentive.d.ts.map +1 -1
- package/dist/Incentives/CGDAIncentive.js +64 -33
- package/dist/Incentives/CGDAIncentive.js.map +1 -1
- package/dist/Incentives/ERC20Incentive.cjs +1 -1
- package/dist/Incentives/ERC20Incentive.cjs.map +1 -1
- package/dist/Incentives/ERC20Incentive.d.ts +37 -1
- package/dist/Incentives/ERC20Incentive.d.ts.map +1 -1
- package/dist/Incentives/ERC20Incentive.js +73 -49
- package/dist/Incentives/ERC20Incentive.js.map +1 -1
- package/dist/Incentives/ERC20PeggedIncentive.d.ts +35 -0
- package/dist/Incentives/ERC20PeggedIncentive.d.ts.map +1 -1
- package/dist/Incentives/ERC20PeggedVariableCriteriaIncentive.d.ts +35 -0
- package/dist/Incentives/ERC20PeggedVariableCriteriaIncentive.d.ts.map +1 -1
- package/dist/Incentives/ERC20VariableCriteriaIncentive.cjs +1 -1
- package/dist/Incentives/ERC20VariableCriteriaIncentive.cjs.map +1 -1
- package/dist/Incentives/ERC20VariableCriteriaIncentive.d.ts +25 -0
- package/dist/Incentives/ERC20VariableCriteriaIncentive.d.ts.map +1 -1
- package/dist/Incentives/ERC20VariableCriteriaIncentive.js +24 -24
- package/dist/Incentives/ERC20VariableCriteriaIncentive.js.map +1 -1
- package/dist/Incentives/ERC20VariableIncentive.cjs +1 -1
- package/dist/Incentives/ERC20VariableIncentive.cjs.map +1 -1
- package/dist/Incentives/ERC20VariableIncentive.d.ts +35 -0
- package/dist/Incentives/ERC20VariableIncentive.d.ts.map +1 -1
- package/dist/Incentives/ERC20VariableIncentive.js +55 -38
- package/dist/Incentives/ERC20VariableIncentive.js.map +1 -1
- package/dist/Incentives/Incentive.cjs +1 -1
- package/dist/Incentives/Incentive.d.ts +25 -0
- package/dist/Incentives/Incentive.d.ts.map +1 -1
- package/dist/Incentives/Incentive.js +2 -2
- package/dist/Incentives/PointsIncentive.cjs +1 -1
- package/dist/Incentives/PointsIncentive.cjs.map +1 -1
- package/dist/Incentives/PointsIncentive.d.ts +8 -0
- package/dist/Incentives/PointsIncentive.d.ts.map +1 -1
- package/dist/Incentives/PointsIncentive.js +50 -28
- package/dist/Incentives/PointsIncentive.js.map +1 -1
- package/dist/SimpleDenyList-CW4RwwRw.js +133 -0
- package/dist/{SimpleDenyList-ByAr4X1r.js.map → SimpleDenyList-CW4RwwRw.js.map} +1 -1
- package/dist/SimpleDenyList-Cybtz7AK.cjs +2 -0
- package/dist/{SimpleDenyList-CsRXJPwm.cjs.map → SimpleDenyList-Cybtz7AK.cjs.map} +1 -1
- package/dist/Validators/LimitedSignerValidator.cjs +1 -1
- package/dist/Validators/LimitedSignerValidator.cjs.map +1 -1
- package/dist/Validators/LimitedSignerValidator.js +33 -33
- package/dist/Validators/LimitedSignerValidator.js.map +1 -1
- package/dist/Validators/SignerValidator.cjs +1 -1
- package/dist/Validators/SignerValidator.cjs.map +1 -1
- package/dist/Validators/SignerValidator.js +26 -26
- package/dist/Validators/SignerValidator.js.map +1 -1
- package/dist/Validators/Validator.cjs +1 -1
- package/dist/Validators/Validator.js +3 -3
- package/dist/deployments-CIXw_WKk.cjs +2 -0
- package/dist/deployments-CIXw_WKk.cjs.map +1 -0
- package/dist/{deployments-D0fs26TV.js → deployments-DqjtOTUr.js} +47 -47
- package/dist/{deployments-D0fs26TV.js.map → deployments-DqjtOTUr.js.map} +1 -1
- package/dist/deployments.json +24 -24
- package/dist/generated-DgXPUgXl.cjs +3 -0
- package/dist/generated-DgXPUgXl.cjs.map +1 -0
- package/dist/{generated-Cyvr_Tjx.js → generated-pJZHmRCK.js} +728 -459
- package/dist/generated-pJZHmRCK.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +137 -136
- package/package.json +1 -1
- package/src/Actions/EventAction.ts +108 -27
- package/src/BoostCore.test.ts +124 -2
- package/src/BoostCore.ts +227 -0
- package/src/Incentives/AllowListIncentive.ts +17 -0
- package/src/Incentives/CGDAIncentive.ts +31 -0
- package/src/Incentives/ERC20Incentive.ts +27 -0
- package/src/Incentives/ERC20PeggedIncentive.ts +18 -0
- package/src/Incentives/ERC20PeggedVariableCriteriaIncentive.ts +26 -0
- package/src/Incentives/ERC20VariableIncentive.ts +18 -0
- package/src/Incentives/PointsIncentive.ts +22 -0
- package/dist/Budget-AoNx7uFd.cjs +0 -2
- package/dist/Budget-DYIV9iNK.js +0 -463
- package/dist/Incentive-BbkfwGOb.cjs +0 -2
- package/dist/Incentive-BbkfwGOb.cjs.map +0 -1
- package/dist/Incentive-qlnv5kQB.js +0 -991
- package/dist/Incentive-qlnv5kQB.js.map +0 -1
- package/dist/SimpleDenyList-ByAr4X1r.js +0 -133
- package/dist/SimpleDenyList-CsRXJPwm.cjs +0 -2
- package/dist/deployments-DoIOqxco.cjs +0 -2
- package/dist/deployments-DoIOqxco.cjs.map +0 -1
- package/dist/generated-Cyvr_Tjx.js.map +0 -1
- package/dist/generated-DtYPHhtX.cjs +0 -3
- package/dist/generated-DtYPHhtX.cjs.map +0 -1
package/src/BoostCore.test.ts
CHANGED
|
@@ -765,8 +765,8 @@ describe("BoostCore", () => {
|
|
|
765
765
|
await new Promise((resolve) => {
|
|
766
766
|
setTimeout(resolve, 500);
|
|
767
767
|
});
|
|
768
|
-
|
|
769
|
-
expect(subscription).toHaveBeenCalledTimes(
|
|
768
|
+
// This should be called once for each event
|
|
769
|
+
expect(subscription).toHaveBeenCalledTimes(2);
|
|
770
770
|
});
|
|
771
771
|
|
|
772
772
|
test("can set a passthrough auth scheme", async () => {
|
|
@@ -953,3 +953,125 @@ describe("BoostCore", () => {
|
|
|
953
953
|
expect(feesInfo.asset.toLowerCase()).toBe(erc20.assertValidAddress());
|
|
954
954
|
});
|
|
955
955
|
});
|
|
956
|
+
|
|
957
|
+
describe("Top-Up Incentives", () => {
|
|
958
|
+
let incentive: ReturnType<typeof fixtures.core.ERC20Incentive>;
|
|
959
|
+
let boostId: bigint;
|
|
960
|
+
|
|
961
|
+
beforeAll(async () => {
|
|
962
|
+
const { core } = fixtures;
|
|
963
|
+
const { budget, erc20 } = budgets;
|
|
964
|
+
|
|
965
|
+
incentive = core.ERC20Incentive({
|
|
966
|
+
asset: erc20.assertValidAddress(),
|
|
967
|
+
strategy: StrategyType.POOL,
|
|
968
|
+
reward: parseEther("1"),
|
|
969
|
+
limit: 5n,
|
|
970
|
+
manager: budget.assertValidAddress(),
|
|
971
|
+
});
|
|
972
|
+
await erc20.mint(defaultOptions.account.address, parseEther("110"));
|
|
973
|
+
await erc20.approve(budget.assertValidAddress(), parseEther("110"));
|
|
974
|
+
await budget.allocate({
|
|
975
|
+
amount: parseEther("110"),
|
|
976
|
+
asset: erc20.assertValidAddress(),
|
|
977
|
+
target: defaultOptions.account.address,
|
|
978
|
+
});
|
|
979
|
+
|
|
980
|
+
|
|
981
|
+
const createdBoost = await core.createBoost({
|
|
982
|
+
protocolFee: 0n,
|
|
983
|
+
maxParticipants: 5n,
|
|
984
|
+
budget,
|
|
985
|
+
action: core.EventAction(
|
|
986
|
+
makeMockEventActionPayload(
|
|
987
|
+
core.assertValidAddress(),
|
|
988
|
+
erc20.assertValidAddress(),
|
|
989
|
+
),
|
|
990
|
+
),
|
|
991
|
+
validator: core.SignerValidator({
|
|
992
|
+
signers: [defaultOptions.account.address],
|
|
993
|
+
validatorCaller: defaultOptions.account.address,
|
|
994
|
+
}),
|
|
995
|
+
allowList: core.SimpleAllowList({
|
|
996
|
+
owner: defaultOptions.account.address,
|
|
997
|
+
allowed: [defaultOptions.account.address],
|
|
998
|
+
}),
|
|
999
|
+
incentives: [incentive],
|
|
1000
|
+
});
|
|
1001
|
+
boostId = createdBoost.id;
|
|
1002
|
+
});
|
|
1003
|
+
|
|
1004
|
+
test("can top up from a budget (pre-fee)", async () => {
|
|
1005
|
+
const { core } = fixtures;
|
|
1006
|
+
const { budget, erc20 } = budgets;
|
|
1007
|
+
|
|
1008
|
+
console.log("budget", budget.assertValidAddress());
|
|
1009
|
+
|
|
1010
|
+
const netTopup = parseEther("5");
|
|
1011
|
+
|
|
1012
|
+
await core.topupIncentiveFromBudgetPreFee(boostId, 0n, netTopup, budget.assertValidAddress());
|
|
1013
|
+
console.log("topup done");
|
|
1014
|
+
|
|
1015
|
+
expect(await incentive.limit()).toBe(5n + 5n); // original limit 5 + topup 5
|
|
1016
|
+
});
|
|
1017
|
+
|
|
1018
|
+
test("can top up from a budget (post-fee)", async () => {
|
|
1019
|
+
const { core } = fixtures;
|
|
1020
|
+
const { budget } = budgets;
|
|
1021
|
+
|
|
1022
|
+
const total = parseEther("5.5");
|
|
1023
|
+
await core.topupIncentiveFromBudgetPostFee(boostId, 0n, total, budget.assertValidAddress());
|
|
1024
|
+
|
|
1025
|
+
expect(await incentive.limit()).toBe(10n + 5n);
|
|
1026
|
+
});
|
|
1027
|
+
|
|
1028
|
+
test("pre-fee and post-fee top-ups lead to the same net top-up", async () => {
|
|
1029
|
+
const { core } = fixtures;
|
|
1030
|
+
const { budget } = budgets;
|
|
1031
|
+
|
|
1032
|
+
const net = parseEther("2");
|
|
1033
|
+
const netPlusFee = parseEther("2.2");
|
|
1034
|
+
|
|
1035
|
+
await core.topupIncentiveFromBudgetPreFee(boostId, 0n, net, budget.assertValidAddress());
|
|
1036
|
+
|
|
1037
|
+
await core.topupIncentiveFromBudgetPostFee(boostId, 0n, netPlusFee, budget.assertValidAddress());
|
|
1038
|
+
|
|
1039
|
+
expect(await incentive.limit()).toBe(15n + 4n);
|
|
1040
|
+
});
|
|
1041
|
+
|
|
1042
|
+
test("can top up from sender (pre-fee)", async () => {
|
|
1043
|
+
const { core } = fixtures;
|
|
1044
|
+
const { erc20 } = budgets;
|
|
1045
|
+
|
|
1046
|
+
const netTopup = parseEther("10");
|
|
1047
|
+
const netPlusFee = parseEther("11");
|
|
1048
|
+
await erc20.mint(defaultOptions.account.address, netPlusFee);
|
|
1049
|
+
await erc20.approve(core.assertValidAddress(), netPlusFee);
|
|
1050
|
+
|
|
1051
|
+
await core.topupIncentiveFromSenderPreFee(boostId, 0n, netTopup);
|
|
1052
|
+
|
|
1053
|
+
expect(await incentive.limit()).toBe(19n + 10n);
|
|
1054
|
+
});
|
|
1055
|
+
|
|
1056
|
+
test("can top up from sender (post-fee)", async () => {
|
|
1057
|
+
const { core } = fixtures;
|
|
1058
|
+
const { erc20 } = budgets;
|
|
1059
|
+
|
|
1060
|
+
const totalWithFee = parseEther("5.5");
|
|
1061
|
+
await erc20.mint(defaultOptions.account.address, totalWithFee);
|
|
1062
|
+
await erc20.approve(core.assertValidAddress(), totalWithFee);
|
|
1063
|
+
|
|
1064
|
+
await core.topupIncentiveFromSenderPostFee(boostId, 0n, totalWithFee);
|
|
1065
|
+
|
|
1066
|
+
expect(await incentive.limit()).toBe(29n + 5n);
|
|
1067
|
+
});
|
|
1068
|
+
|
|
1069
|
+
test("throws if net top-up is zero", async () => {
|
|
1070
|
+
const { core } = fixtures;
|
|
1071
|
+
const { budget } = budgets;
|
|
1072
|
+
|
|
1073
|
+
await expect(async () => {
|
|
1074
|
+
await core.topupIncentiveFromBudgetPreFee(boostId, 0n, 0n, budget.assertValidAddress());
|
|
1075
|
+
}).rejects.toThrowError();
|
|
1076
|
+
});
|
|
1077
|
+
});
|
package/src/BoostCore.ts
CHANGED
|
@@ -12,11 +12,15 @@ import {
|
|
|
12
12
|
simulateBoostCoreCreateBoost,
|
|
13
13
|
simulateBoostCoreSetCreateBoostAuth,
|
|
14
14
|
simulateBoostCoreSetProtocolFeeReceiver,
|
|
15
|
+
simulateBoostCoreTopupIncentiveFromBudget,
|
|
16
|
+
simulateBoostCoreTopupIncentiveFromSender,
|
|
15
17
|
writeBoostCoreClaimIncentive,
|
|
16
18
|
writeBoostCoreClaimIncentiveFor,
|
|
17
19
|
writeBoostCoreCreateBoost,
|
|
18
20
|
writeBoostCoreSetCreateBoostAuth,
|
|
19
21
|
writeBoostCoreSetProtocolFeeReceiver,
|
|
22
|
+
writeBoostCoreTopupIncentiveFromBudget,
|
|
23
|
+
writeBoostCoreTopupIncentiveFromSender,
|
|
20
24
|
} from '@boostxyz/evm';
|
|
21
25
|
import { bytecode } from '@boostxyz/evm/artifacts/contracts/BoostCore.sol/BoostCore.json';
|
|
22
26
|
import {
|
|
@@ -24,6 +28,7 @@ import {
|
|
|
24
28
|
getAccount,
|
|
25
29
|
getChains,
|
|
26
30
|
getTransactionReceipt,
|
|
31
|
+
readContract,
|
|
27
32
|
waitForTransactionReceipt,
|
|
28
33
|
} from '@wagmi/core';
|
|
29
34
|
import { createWriteContract } from '@wagmi/core/codegen';
|
|
@@ -31,6 +36,8 @@ import {
|
|
|
31
36
|
type Address,
|
|
32
37
|
type ContractEventName,
|
|
33
38
|
type Hex,
|
|
39
|
+
decodeAbiParameters,
|
|
40
|
+
encodeAbiParameters,
|
|
34
41
|
encodePacked,
|
|
35
42
|
keccak256,
|
|
36
43
|
parseEventLogs,
|
|
@@ -1654,4 +1661,224 @@ export class BoostCore extends Deployable<
|
|
|
1654
1661
|
...this.optionallyAttachAccount(options.account),
|
|
1655
1662
|
};
|
|
1656
1663
|
}
|
|
1664
|
+
/**
|
|
1665
|
+
* Prepares and executes a top-up from a Budget, specifying the net top-up amount
|
|
1666
|
+
* that should land in the incentive (the protocol fee is added automatically).
|
|
1667
|
+
*
|
|
1668
|
+
* @public
|
|
1669
|
+
* @async
|
|
1670
|
+
* @param {bigint} boostId The ID of the Boost
|
|
1671
|
+
* @param {bigint} incentiveId The ID of the incentive within that Boost
|
|
1672
|
+
* @param {any} topupPayload A typed struct for the incentive’s top-up parameters
|
|
1673
|
+
* @param {Address} [budget] Optional override budget address (otherwise uses the Boost’s budget)
|
|
1674
|
+
* @param {?WriteParams} [params] Additional transaction overrides
|
|
1675
|
+
* @returns {Promise<{ hash: Hex; result: void }>} The transaction hash and simulation result
|
|
1676
|
+
*/
|
|
1677
|
+
public async topupIncentiveFromBudgetPreFee(
|
|
1678
|
+
boostId: bigint,
|
|
1679
|
+
incentiveId: bigint,
|
|
1680
|
+
topupAmount: bigint,
|
|
1681
|
+
budget?: Address,
|
|
1682
|
+
params?: WriteParams,
|
|
1683
|
+
) {
|
|
1684
|
+
const boost = await this.getBoost(boostId, params);
|
|
1685
|
+
if (incentiveId >= boost.incentives.length) {
|
|
1686
|
+
throw new Error(`Incentive ID ${incentiveId} out of range`);
|
|
1687
|
+
}
|
|
1688
|
+
const incentive = boost.incentives[Number(incentiveId)];
|
|
1689
|
+
if (!incentive) {
|
|
1690
|
+
throw new Error(`Incentive with ID ${incentiveId} not found`);
|
|
1691
|
+
}
|
|
1692
|
+
|
|
1693
|
+
const incentiveData = await incentive.getTopupPayload(topupAmount);
|
|
1694
|
+
|
|
1695
|
+
if (!(topupAmount > 0)) {
|
|
1696
|
+
throw new Error('Top-up amount must be greater than zero');
|
|
1697
|
+
}
|
|
1698
|
+
|
|
1699
|
+
return await this.topupIncentiveFromBudgetRaw(
|
|
1700
|
+
boostId,
|
|
1701
|
+
incentiveId,
|
|
1702
|
+
incentiveData,
|
|
1703
|
+
budget,
|
|
1704
|
+
params,
|
|
1705
|
+
);
|
|
1706
|
+
}
|
|
1707
|
+
|
|
1708
|
+
/**
|
|
1709
|
+
* Prepares and executes a top-up from a Budget, specifying the entire total tokens
|
|
1710
|
+
* (incentive + fee) you want to disburse. We'll back-calculate how many tokens land
|
|
1711
|
+
* in the incentive.
|
|
1712
|
+
*
|
|
1713
|
+
* @public
|
|
1714
|
+
* @async
|
|
1715
|
+
* @param {bigint} boostId The ID of the Boost
|
|
1716
|
+
* @param {bigint} incentiveId The ID of the incentive within that Boost
|
|
1717
|
+
* @param {any} topupPayload A typed struct for the incentive’s top-up parameters
|
|
1718
|
+
* @param {bigint} totalAmount The total tokens to disburse
|
|
1719
|
+
* @param {Address} [budget] Optional override budget address
|
|
1720
|
+
* @param {?WriteParams} [params] Additional transaction overrides
|
|
1721
|
+
* @returns {Promise<{ hash: Hex; result: void }>}
|
|
1722
|
+
*/
|
|
1723
|
+
public async topupIncentiveFromBudgetPostFee(
|
|
1724
|
+
boostId: bigint,
|
|
1725
|
+
incentiveId: bigint,
|
|
1726
|
+
totalAmount: bigint,
|
|
1727
|
+
budget?: Address,
|
|
1728
|
+
params?: WriteParams,
|
|
1729
|
+
) {
|
|
1730
|
+
const feeBps = await this.protocolFee(params);
|
|
1731
|
+
const topupAmount =
|
|
1732
|
+
(totalAmount * FEE_DENOMINATOR) / (FEE_DENOMINATOR + feeBps);
|
|
1733
|
+
return this.topupIncentiveFromBudgetPreFee(
|
|
1734
|
+
boostId,
|
|
1735
|
+
incentiveId,
|
|
1736
|
+
topupAmount,
|
|
1737
|
+
budget,
|
|
1738
|
+
params,
|
|
1739
|
+
);
|
|
1740
|
+
}
|
|
1741
|
+
|
|
1742
|
+
/**
|
|
1743
|
+
* Prepares and executes a top-up from the caller (msg.sender), specifying the net top-up
|
|
1744
|
+
* to land in the incentive. We'll add the protocol fee on top automatically.
|
|
1745
|
+
*
|
|
1746
|
+
* @public
|
|
1747
|
+
* @async
|
|
1748
|
+
* @param {bigint} boostId The ID of the Boost
|
|
1749
|
+
* @param {bigint} incentiveId The ID of the incentive within that Boost
|
|
1750
|
+
* @param {any} topupPayload A typed struct for the incentive’s top-up parameters
|
|
1751
|
+
* @param {?WriteParams} [params]
|
|
1752
|
+
* @returns {Promise<{ hash: Hex; result: void }>}
|
|
1753
|
+
*/
|
|
1754
|
+
public async topupIncentiveFromSenderPreFee(
|
|
1755
|
+
boostId: bigint,
|
|
1756
|
+
incentiveId: bigint,
|
|
1757
|
+
topupAmount: bigint,
|
|
1758
|
+
params?: WriteParams,
|
|
1759
|
+
) {
|
|
1760
|
+
const boost = await this.getBoost(boostId, params);
|
|
1761
|
+
if (incentiveId >= boost.incentives.length) {
|
|
1762
|
+
throw new Error(`Incentive ID ${incentiveId} out of range`);
|
|
1763
|
+
}
|
|
1764
|
+
const incentive = boost.incentives[Number(incentiveId)];
|
|
1765
|
+
if (!incentive) {
|
|
1766
|
+
throw new Error(`Incentive with ID ${incentiveId} not found`);
|
|
1767
|
+
}
|
|
1768
|
+
|
|
1769
|
+
if (!(topupAmount > 0)) {
|
|
1770
|
+
throw new Error('Top-up amount must be greater than zero');
|
|
1771
|
+
}
|
|
1772
|
+
|
|
1773
|
+
const incentiveData = await incentive.getTopupPayload(topupAmount);
|
|
1774
|
+
|
|
1775
|
+
return await this.topupIncentiveFromSenderRaw(
|
|
1776
|
+
boostId,
|
|
1777
|
+
incentiveId,
|
|
1778
|
+
incentiveData,
|
|
1779
|
+
params,
|
|
1780
|
+
);
|
|
1781
|
+
}
|
|
1782
|
+
|
|
1783
|
+
/**
|
|
1784
|
+
* Prepares and executes a top-up from the caller (msg.sender), specifying the total
|
|
1785
|
+
* tokens you’re willing to provide (including fee). We'll back-calculate the net
|
|
1786
|
+
* top-up for the incentive.
|
|
1787
|
+
*
|
|
1788
|
+
* @public
|
|
1789
|
+
* @async
|
|
1790
|
+
* @param {bigint} boostId The ID of the Boost
|
|
1791
|
+
* @param {bigint} incentiveId The ID of the incentive within that Boost
|
|
1792
|
+
* @param {any} topupPayload A typed struct for the incentive’s top-up parameters
|
|
1793
|
+
* @param {bigint} totalAmount The entire tokens (top-up + fee)
|
|
1794
|
+
* @param {?WriteParams} [params]
|
|
1795
|
+
* @returns {Promise<{ hash: Hex; result: void }>}
|
|
1796
|
+
*/
|
|
1797
|
+
public async topupIncentiveFromSenderPostFee(
|
|
1798
|
+
boostId: bigint,
|
|
1799
|
+
incentiveId: bigint,
|
|
1800
|
+
totalAmount: bigint,
|
|
1801
|
+
params?: WriteParams,
|
|
1802
|
+
) {
|
|
1803
|
+
const feeBps = await this.protocolFee(params);
|
|
1804
|
+
const topupAmount =
|
|
1805
|
+
(totalAmount * FEE_DENOMINATOR) / (FEE_DENOMINATOR + feeBps);
|
|
1806
|
+
|
|
1807
|
+
return this.topupIncentiveFromSenderPreFee(
|
|
1808
|
+
boostId,
|
|
1809
|
+
incentiveId,
|
|
1810
|
+
topupAmount,
|
|
1811
|
+
params,
|
|
1812
|
+
);
|
|
1813
|
+
}
|
|
1814
|
+
|
|
1815
|
+
/**
|
|
1816
|
+
* A lower-level function that actually calls `topupIncentiveFromSender` on-chain,
|
|
1817
|
+
* passing the final total. The contract modifies its internal logic to split net top-up vs. fee.
|
|
1818
|
+
*
|
|
1819
|
+
* @private
|
|
1820
|
+
* @param {bigint} boostId
|
|
1821
|
+
* @param {bigint} incentiveId
|
|
1822
|
+
* @param {Hex} preflightData The raw ABudget.Transfer data from preflight
|
|
1823
|
+
* @param {?WriteParams} [params]
|
|
1824
|
+
* @returns {Promise<{ hash: Hex; result: void }>}
|
|
1825
|
+
*/
|
|
1826
|
+
private async topupIncentiveFromSenderRaw(
|
|
1827
|
+
boostId: bigint,
|
|
1828
|
+
incentiveId: bigint,
|
|
1829
|
+
preflightData: Hex,
|
|
1830
|
+
params?: WriteParams,
|
|
1831
|
+
) {
|
|
1832
|
+
const { request, result } = await simulateBoostCoreTopupIncentiveFromSender(
|
|
1833
|
+
this._config,
|
|
1834
|
+
{
|
|
1835
|
+
...this.optionallyAttachAccount(),
|
|
1836
|
+
...(params as object),
|
|
1837
|
+
address: this.assertValidAddress(),
|
|
1838
|
+
args: [boostId, incentiveId, preflightData],
|
|
1839
|
+
},
|
|
1840
|
+
);
|
|
1841
|
+
const hash = await writeBoostCoreTopupIncentiveFromSender(
|
|
1842
|
+
this._config,
|
|
1843
|
+
request,
|
|
1844
|
+
);
|
|
1845
|
+
return { hash, result };
|
|
1846
|
+
}
|
|
1847
|
+
|
|
1848
|
+
/**
|
|
1849
|
+
* A lower-level function that actually calls `topupIncentiveFromBudget` on-chain,
|
|
1850
|
+
* passing the preflight data plus the final total. The contract itself modifies
|
|
1851
|
+
* the amount to (topup + fee).
|
|
1852
|
+
*
|
|
1853
|
+
* @private
|
|
1854
|
+
* @param {bigint} boostId
|
|
1855
|
+
* @param {bigint} incentiveId
|
|
1856
|
+
* @param {Hex} preflightData The raw ABudget.Transfer (encoded) from preflight
|
|
1857
|
+
* @param {Address} [budget] Optional override for the budget
|
|
1858
|
+
* @param {?WriteParams} [params]
|
|
1859
|
+
* @returns {Promise<{ hash: Hex; result: void }>}
|
|
1860
|
+
*/
|
|
1861
|
+
private async topupIncentiveFromBudgetRaw(
|
|
1862
|
+
boostId: bigint,
|
|
1863
|
+
incentiveId: bigint,
|
|
1864
|
+
preflightData: Hex,
|
|
1865
|
+
budget?: Address,
|
|
1866
|
+
params?: WriteParams,
|
|
1867
|
+
) {
|
|
1868
|
+
// e.g. run "simulate + write" pattern
|
|
1869
|
+
const { request, result } = await simulateBoostCoreTopupIncentiveFromBudget(
|
|
1870
|
+
this._config,
|
|
1871
|
+
{
|
|
1872
|
+
...this.optionallyAttachAccount(),
|
|
1873
|
+
...(params as object),
|
|
1874
|
+
address: this.assertValidAddress(),
|
|
1875
|
+
args: [boostId, incentiveId, preflightData, budget ?? zeroAddress],
|
|
1876
|
+
},
|
|
1877
|
+
);
|
|
1878
|
+
const hash = await writeBoostCoreTopupIncentiveFromBudget(
|
|
1879
|
+
this._config,
|
|
1880
|
+
request,
|
|
1881
|
+
);
|
|
1882
|
+
return { hash, result };
|
|
1883
|
+
}
|
|
1657
1884
|
}
|
|
@@ -330,6 +330,23 @@ export class AllowListIncentive extends DeployableTarget<
|
|
|
330
330
|
};
|
|
331
331
|
}
|
|
332
332
|
|
|
333
|
+
/**
|
|
334
|
+
* Generates a top-up payload for the AllowListIncentive contract.
|
|
335
|
+
*
|
|
336
|
+
* @public
|
|
337
|
+
* @param {bigint} netAmount The net number of slots to be added to the allowlist.
|
|
338
|
+
* @returns {Hex} The ABI-encoded top-up payload.
|
|
339
|
+
*/
|
|
340
|
+
public getTopupPayload(netAmount: bigint): Hex {
|
|
341
|
+
return encodeAbiParameters(
|
|
342
|
+
[
|
|
343
|
+
{ type: 'address', name: 'allowList' },
|
|
344
|
+
{ type: 'uint256', name: 'limit' },
|
|
345
|
+
],
|
|
346
|
+
[this.payload?.allowList ?? zeroHash, netAmount],
|
|
347
|
+
);
|
|
348
|
+
}
|
|
349
|
+
|
|
333
350
|
/**
|
|
334
351
|
* Builds the claim data for the AllowListIncentive.
|
|
335
352
|
*
|
|
@@ -482,6 +482,37 @@ export class CGDAIncentive extends DeployableTarget<
|
|
|
482
482
|
return encodeAbiParameters([{ type: 'uint256' }], [amount]);
|
|
483
483
|
}
|
|
484
484
|
|
|
485
|
+
/**
|
|
486
|
+
* Generates a top-up payload for the CGDAIncentive contract.
|
|
487
|
+
*
|
|
488
|
+
* In this approach, we treat a "top-up" as incrementing the existing `totalBudget`
|
|
489
|
+
* in the incentive by `netAmount`. The entire payload is re-encoded with the updated budget.
|
|
490
|
+
*
|
|
491
|
+
* @public
|
|
492
|
+
* @param {bigint} netAmount The additional tokens to add to `totalBudget`.
|
|
493
|
+
* @returns {Hex} The ABI-encoded, updated CGDAIncentive payload.
|
|
494
|
+
*/
|
|
495
|
+
public async getTopupPayload(netAmount: bigint): Promise<Hex> {
|
|
496
|
+
return encodeAbiParameters(
|
|
497
|
+
[
|
|
498
|
+
{ type: 'address', name: 'asset' },
|
|
499
|
+
{ type: 'uint256', name: 'initialReward' },
|
|
500
|
+
{ type: 'uint256', name: 'rewardDecay' },
|
|
501
|
+
{ type: 'uint256', name: 'rewardBoost' },
|
|
502
|
+
{ type: 'uint256', name: 'totalBudget' },
|
|
503
|
+
{ type: 'address', name: 'manager' },
|
|
504
|
+
],
|
|
505
|
+
[
|
|
506
|
+
(await this.asset()) ?? zeroHash,
|
|
507
|
+
this.payload?.initialReward ?? 0n,
|
|
508
|
+
this.payload?.rewardDecay ?? 0n,
|
|
509
|
+
this.payload?.rewardBoost ?? 0n,
|
|
510
|
+
netAmount,
|
|
511
|
+
this.payload?.manager ?? zeroHash,
|
|
512
|
+
],
|
|
513
|
+
);
|
|
514
|
+
}
|
|
515
|
+
|
|
485
516
|
/**
|
|
486
517
|
* Builds the claim data for the CGDAIncentive.
|
|
487
518
|
*
|
|
@@ -502,6 +502,33 @@ export class ERC20Incentive extends DeployableTarget<
|
|
|
502
502
|
return encodeAbiParameters([{ type: 'uint256' }], [amount]);
|
|
503
503
|
}
|
|
504
504
|
|
|
505
|
+
/**
|
|
506
|
+
* A helper that composes a typed "top-up" parameter object
|
|
507
|
+
* given a net top-up amount. You can name it whatever you like
|
|
508
|
+
* (e.g. topupParamsFromNetAmount, getTopupPayload, etc.).
|
|
509
|
+
*
|
|
510
|
+
* @public
|
|
511
|
+
* @param {bigint} netAmount The net top-up tokens the user wants to add
|
|
512
|
+
* @param {?WriteParams} [params] (optional) if you need them
|
|
513
|
+
* @returns {Hex} the ABI-encoded data for top-up
|
|
514
|
+
*/
|
|
515
|
+
public async getTopupPayload(netAmount: bigint): Promise<Hex> {
|
|
516
|
+
// 1. Build a typed object matching your `ERC20IncentivePayload`.
|
|
517
|
+
// For example, you might want to increment `limit` by `netAmount`,
|
|
518
|
+
// or set `reward = netAmount`. That’s up to your logic:
|
|
519
|
+
const asset = await this.asset();
|
|
520
|
+
const typed: ERC20IncentivePayload = {
|
|
521
|
+
asset: asset || zeroAddress,
|
|
522
|
+
strategy: StrategyType.POOL, // e.g. StrategyType.POOL
|
|
523
|
+
reward: 1n, // store net top-up as the "reward"
|
|
524
|
+
limit: netAmount, // or maybe add netAmount to existing limit
|
|
525
|
+
manager: this.payload?.manager || zeroAddress,
|
|
526
|
+
};
|
|
527
|
+
|
|
528
|
+
// 2. Encode it with your existing `prepareERC20IncentivePayload(...)`.
|
|
529
|
+
return prepareERC20IncentivePayload(typed);
|
|
530
|
+
}
|
|
531
|
+
|
|
505
532
|
/**
|
|
506
533
|
* Builds the claim data for the ERC20Incentive.
|
|
507
534
|
*
|
|
@@ -478,6 +478,24 @@ export class ERC20PeggedIncentive extends DeployableTarget<
|
|
|
478
478
|
[rewardAmount],
|
|
479
479
|
);
|
|
480
480
|
}
|
|
481
|
+
/**
|
|
482
|
+
* Generates a top-up payload for the ERC20PeggedIncentive contract by incrementing
|
|
483
|
+
* the existing `limit` field by `netAmount`. The entire payload is then re-encoded
|
|
484
|
+
* via `prepareERC20PeggedIncentivePayload(...)`.
|
|
485
|
+
*
|
|
486
|
+
* @public
|
|
487
|
+
* @param {bigint} netAmount - The additional limit to add to this incentive.
|
|
488
|
+
* @returns {Hex} The ABI-encoded payload with the updated `limit`.
|
|
489
|
+
*/
|
|
490
|
+
public async getTopupPayload(netAmount: bigint): Promise<Hex> {
|
|
491
|
+
return prepareERC20PeggedIncentivePayload({
|
|
492
|
+
asset: (await this.asset()) ?? zeroAddress,
|
|
493
|
+
peg: this.payload?.peg ?? zeroAddress,
|
|
494
|
+
reward: this.payload?.reward ?? 0n,
|
|
495
|
+
limit: netAmount,
|
|
496
|
+
manager: this.payload?.manager ?? zeroAddress,
|
|
497
|
+
});
|
|
498
|
+
}
|
|
481
499
|
|
|
482
500
|
/**
|
|
483
501
|
* Decodes claim data for the ERC20PeggedIncentive, returning the claim amount.
|
|
@@ -613,6 +613,32 @@ export class ERC20PeggedVariableCriteriaIncentive extends DeployableTarget<
|
|
|
613
613
|
}
|
|
614
614
|
}
|
|
615
615
|
|
|
616
|
+
/**
|
|
617
|
+
* Generates a top-up payload for the ERC20PeggedIncentive contract by incrementing
|
|
618
|
+
* the existing `limit` field by `netAmount`. The entire payload is then re-encoded
|
|
619
|
+
* via `prepareERC20PeggedIncentivePayload(...)`.
|
|
620
|
+
*
|
|
621
|
+
* @public
|
|
622
|
+
* @param {bigint} netAmount - The additional limit to add to this incentive.
|
|
623
|
+
* @returns {Hex} The ABI-encoded payload with the updated `limit`.
|
|
624
|
+
*/
|
|
625
|
+
public async getTopupPayload(netAmount: bigint): Promise<Hex> {
|
|
626
|
+
return prepareERC20PeggedVariableCriteriaIncentivePayload({
|
|
627
|
+
asset: (await this.asset()) ?? zeroAddress,
|
|
628
|
+
peg: this.payload?.peg ?? zeroAddress,
|
|
629
|
+
reward: this.payload?.reward ?? 0n,
|
|
630
|
+
limit: netAmount,
|
|
631
|
+
maxReward: this.payload?.maxReward ?? 0n,
|
|
632
|
+
manager: this.payload?.manager ?? zeroAddress,
|
|
633
|
+
criteria: this.payload?.criteria ?? {
|
|
634
|
+
criteriaType: 0,
|
|
635
|
+
signature: zeroAddress,
|
|
636
|
+
fieldIndex: 0,
|
|
637
|
+
targetContract: zeroAddress,
|
|
638
|
+
},
|
|
639
|
+
});
|
|
640
|
+
}
|
|
641
|
+
|
|
616
642
|
/**
|
|
617
643
|
* @inheritdoc
|
|
618
644
|
*
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
type Hex,
|
|
23
23
|
decodeAbiParameters,
|
|
24
24
|
encodeAbiParameters,
|
|
25
|
+
zeroAddress,
|
|
25
26
|
} from 'viem';
|
|
26
27
|
import { ERC20VariableIncentive as ERC20VariableIncentiveBases } from '../../dist/deployments.json';
|
|
27
28
|
import type {
|
|
@@ -394,6 +395,23 @@ export class ERC20VariableIncentive<
|
|
|
394
395
|
]);
|
|
395
396
|
return limit - totalClaimed;
|
|
396
397
|
}
|
|
398
|
+
/**
|
|
399
|
+
* Generates a top-up payload for the ERC20PeggedIncentive contract by incrementing
|
|
400
|
+
* the existing `limit` field by `netAmount`. The entire payload is then re-encoded
|
|
401
|
+
* via `prepareERC20PeggedIncentivePayload(...)`.
|
|
402
|
+
*
|
|
403
|
+
* @public
|
|
404
|
+
* @param {bigint} netAmount - The additional limit to add to this incentive.
|
|
405
|
+
* @returns {Hex} The ABI-encoded payload with the updated `limit`.
|
|
406
|
+
*/
|
|
407
|
+
public async getTopupPayload(netAmount: bigint): Promise<Hex> {
|
|
408
|
+
return prepareERC20VariableIncentivePayload({
|
|
409
|
+
asset: (await this.asset()) as Address,
|
|
410
|
+
reward: netAmount,
|
|
411
|
+
manager: zeroAddress,
|
|
412
|
+
limit: 1n,
|
|
413
|
+
});
|
|
414
|
+
}
|
|
397
415
|
|
|
398
416
|
/**
|
|
399
417
|
* Builds the claim data for the ERC20VariableIncentive.
|
|
@@ -348,6 +348,28 @@ export class PointsIncentive extends DeployableTarget<
|
|
|
348
348
|
};
|
|
349
349
|
}
|
|
350
350
|
|
|
351
|
+
/**
|
|
352
|
+
* Generates a top-up payload for the PointsIncentive contract.
|
|
353
|
+
*
|
|
354
|
+
* @public
|
|
355
|
+
* @param {bigint} netAmount The net reward amount to be added to the incentive.
|
|
356
|
+
* @returns {Hex} The ABI-encoded top-up payload.
|
|
357
|
+
*/
|
|
358
|
+
public getTopupPayload(netAmount: bigint): Hex {
|
|
359
|
+
return encodeAbiParameters(
|
|
360
|
+
[
|
|
361
|
+
{ type: 'address', name: 'venue' },
|
|
362
|
+
{ type: 'bytes4', name: 'selector' },
|
|
363
|
+
{ type: 'uint256', name: 'amount' },
|
|
364
|
+
],
|
|
365
|
+
[
|
|
366
|
+
this.payload?.venue ?? zeroHash,
|
|
367
|
+
this.payload?.selector ?? zeroHash,
|
|
368
|
+
netAmount,
|
|
369
|
+
],
|
|
370
|
+
);
|
|
371
|
+
}
|
|
372
|
+
|
|
351
373
|
/**
|
|
352
374
|
* Builds the claim data for the PointsIncentive.
|
|
353
375
|
*
|