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