Skip to content

Commit 36ca0c7

Browse files
committed
Implement receive function and update campaign management to handle ETH payments
1 parent 1d4fa13 commit 36ca0c7

File tree

2 files changed

+53
-111
lines changed

2 files changed

+53
-111
lines changed

contracts/contracts/strategies/CurvePoolBooster.sol

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,4 +382,6 @@ contract CurvePoolBooster is Initializable, Strategizable {
382382
function min(uint256 a, uint256 b) internal pure returns (uint256) {
383383
return a < b ? a : b;
384384
}
385+
386+
receive() external payable {}
385387
}

contracts/test/strategies/curvePoolBooster.mainnet.fork-test.js

Lines changed: 51 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -67,22 +67,12 @@ describe("ForkTest: CurvePoolBooster", function () {
6767
parseUnits("10")
6868
);
6969

70-
// Deal ETH to pool booster
71-
await sStrategist.sendTransaction({
72-
to: curvePoolBooster.address,
73-
value: parseUnits("1"),
74-
});
75-
7670
// Create campaign
7771
await curvePoolBooster
7872
.connect(sStrategist)
79-
.createCampaign(
80-
4,
81-
10,
82-
[addresses.mainnet.ConvexVoter],
83-
parseUnits("0.1"),
84-
0
85-
);
73+
.createCampaign(4, 10, [addresses.mainnet.ConvexVoter], 0, {
74+
value: parseUnits("0.1"),
75+
});
8676
}
8777

8878
// --- Initialization ---
@@ -143,9 +133,13 @@ describe("ForkTest: CurvePoolBooster", function () {
143133

144134
await curvePoolBooster.connect(sStrategist).setCampaignId(12);
145135

136+
// manageCampaign(totalRewardAmount, numberOfPeriods, maxRewardPerVote, additionalGasLimit)
137+
// Use type(uint256).max to send all tokens
146138
await curvePoolBooster
147139
.connect(sStrategist)
148-
.manageTotalRewardAmount(parseUnits("0.1"), 0);
140+
.manageCampaign(ethers.constants.MaxUint256, 0, 0, 0, {
141+
value: parseUnits("0.1"),
142+
});
149143
expect(await ousd.balanceOf(curvePoolBooster.address)).to.equal(
150144
parseUnits("0")
151145
);
@@ -156,55 +150,37 @@ describe("ForkTest: CurvePoolBooster", function () {
156150

157151
await curvePoolBooster.connect(sStrategist).setCampaignId(12);
158152

159-
await curvePoolBooster
160-
.connect(sStrategist)
161-
.manageNumberOfPeriods(2, parseUnits("0.1"), 0);
153+
// manageCampaign(totalRewardAmount, numberOfPeriods, maxRewardPerVote, additionalGasLimit)
154+
await curvePoolBooster.connect(sStrategist).manageCampaign(0, 2, 0, 0, {
155+
value: parseUnits("0.1"),
156+
});
162157
});
163158

164159
it("Should manage reward per voter", async () => {
165160
await dealOETHAndCreateCampaign();
166161

167-
// Deal new OETH to pool booster
168-
await ousd
169-
.connect(woethSigner)
170-
.transfer(curvePoolBooster.address, parseUnits("13"));
171-
expect(await ousd.balanceOf(curvePoolBooster.address)).to.equal(
172-
parseUnits("13")
173-
);
174-
175162
await curvePoolBooster.connect(sStrategist).setCampaignId(12);
176163

177-
await curvePoolBooster
178-
.connect(sStrategist)
179-
.manageRewardPerVote(100, parseUnits("0.1"), 0);
164+
// manageCampaign(totalRewardAmount, numberOfPeriods, maxRewardPerVote, additionalGasLimit)
165+
await curvePoolBooster.connect(sStrategist).manageCampaign(0, 0, 100, 0, {
166+
value: parseUnits("0.1"),
167+
});
180168
});
181169

182170
it("Should close a campaign", async () => {
183171
await dealOETHAndCreateCampaign();
184172

185-
await curvePoolBooster
186-
.connect(sStrategist)
187-
.closeCampaign(12, parseUnits("0.1"), 0);
173+
await curvePoolBooster.connect(sStrategist).closeCampaign(12, 0, {
174+
value: parseUnits("0.1"),
175+
});
188176
});
189177

190178
it("Should revert if not called by operator", async () => {
191179
await expect(
192-
curvePoolBooster.createCampaign(
193-
4,
194-
10,
195-
[addresses.mainnet.ConvexVoter],
196-
parseUnits("0.1"),
197-
0
198-
)
180+
curvePoolBooster.createCampaign(4, 10, [addresses.mainnet.ConvexVoter], 0)
199181
).to.be.revertedWith("Caller is not the Strategist or Governor");
200182
await expect(
201-
curvePoolBooster.manageTotalRewardAmount(parseUnits("0.1"), 0)
202-
).to.be.revertedWith("Caller is not the Strategist or Governor");
203-
await expect(
204-
curvePoolBooster.manageNumberOfPeriods(2, parseUnits("0.1"), 0)
205-
).to.be.revertedWith("Caller is not the Strategist or Governor");
206-
await expect(
207-
curvePoolBooster.manageRewardPerVote(100, parseUnits("0.1"), 0)
183+
curvePoolBooster.manageCampaign(ethers.constants.MaxUint256, 0, 0, 0)
208184
).to.be.revertedWith("Caller is not the Strategist or Governor");
209185
await expect(curvePoolBooster.setCampaignId(12)).to.be.revertedWith(
210186
"Caller is not the Strategist or Governor"
@@ -217,96 +193,62 @@ describe("ForkTest: CurvePoolBooster", function () {
217193
await expect(
218194
curvePoolBooster
219195
.connect(sStrategist)
220-
.createCampaign(
221-
4,
222-
10,
223-
[addresses.mainnet.ConvexVoter],
224-
parseUnits("0.1"),
225-
0
226-
)
196+
.createCampaign(4, 10, [addresses.mainnet.ConvexVoter], 0)
227197
).to.be.revertedWith("Campaign already created");
228198
});
229199

230200
it("Should create another campaign if campaign is closed", async () => {
231201
await curvePoolBooster.connect(sStrategist).setCampaignId(12);
232-
await curvePoolBooster
233-
.connect(sStrategist)
234-
.closeCampaign(12, parseUnits("0.1"), 0);
202+
await curvePoolBooster.connect(sStrategist).closeCampaign(12, 0, {
203+
value: parseUnits("0.1"),
204+
});
235205

236206
expect(await curvePoolBooster.campaignId()).to.equal(0);
237207

238208
// Create campaign
239209
await curvePoolBooster
240210
.connect(sStrategist)
241-
.createCampaign(
242-
4,
243-
10,
244-
[addresses.mainnet.ConvexVoter],
245-
parseUnits("0.1"),
246-
0
247-
);
211+
.createCampaign(4, 10, [addresses.mainnet.ConvexVoter], 0, {
212+
value: parseUnits("0.1"),
213+
});
248214
});
249215

250216
it("Should revert if campaign is not created", async () => {
251217
await expect(
252218
curvePoolBooster
253219
.connect(sStrategist)
254-
.manageTotalRewardAmount(parseUnits("0.1"), 0)
255-
).to.be.revertedWith("Campaign not created");
256-
await expect(
257-
curvePoolBooster
258-
.connect(sStrategist)
259-
.manageNumberOfPeriods(2, parseUnits("0.1"), 0)
260-
).to.be.revertedWith("Campaign not created");
261-
await expect(
262-
curvePoolBooster
263-
.connect(sStrategist)
264-
.manageRewardPerVote(100, parseUnits("0.1"), 0)
220+
.manageCampaign(ethers.constants.MaxUint256, 0, 0, 0, {
221+
value: parseUnits("0.1"),
222+
})
265223
).to.be.revertedWith("Campaign not created");
266224
});
267225

268226
it("Should revert if Invalid number of periods", async () => {
227+
// createCampaign requires numberOfPeriods > 1
269228
await expect(
270229
curvePoolBooster
271230
.connect(sStrategist)
272-
.createCampaign(
273-
0,
274-
10,
275-
[addresses.mainnet.ConvexVoter],
276-
parseUnits("0.1"),
277-
0
278-
)
231+
.createCampaign(0, 10, [addresses.mainnet.ConvexVoter], 0)
279232
).to.be.revertedWith("Invalid number of periods");
280233

281-
await curvePoolBooster.connect(sStrategist).setCampaignId(12);
282-
283234
await expect(
284235
curvePoolBooster
285236
.connect(sStrategist)
286-
.manageNumberOfPeriods(0, parseUnits("0.1"), 0)
237+
.createCampaign(1, 10, [addresses.mainnet.ConvexVoter], 0)
287238
).to.be.revertedWith("Invalid number of periods");
239+
240+
// Note: manageCampaign with numberOfPeriods=0 means "no update", so it won't revert
288241
});
289242

290243
it("Should revert if Invalid reward per vote", async () => {
244+
// createCampaign requires maxRewardPerVote > 0
291245
await expect(
292246
curvePoolBooster
293247
.connect(sStrategist)
294-
.createCampaign(
295-
4,
296-
0,
297-
[addresses.mainnet.ConvexVoter],
298-
parseUnits("0.1"),
299-
0
300-
)
248+
.createCampaign(4, 0, [addresses.mainnet.ConvexVoter], 0)
301249
).to.be.revertedWith("Invalid reward per vote");
302250

303-
await curvePoolBooster.connect(sStrategist).setCampaignId(12);
304-
305-
await expect(
306-
curvePoolBooster
307-
.connect(sStrategist)
308-
.manageRewardPerVote(0, parseUnits("0.1"), 0)
309-
).to.be.revertedWith("Invalid reward per vote");
251+
// Note: manageCampaign with maxRewardPerVote=0 means "no update", so it won't revert
310252
});
311253

312254
it("Should revert if No reward to manage", async () => {
@@ -322,29 +264,27 @@ describe("ForkTest: CurvePoolBooster", function () {
322264
await expect(
323265
curvePoolBooster
324266
.connect(sStrategist)
325-
.createCampaign(
326-
4,
327-
10,
328-
[addresses.mainnet.ConvexVoter],
329-
parseUnits("0.1"),
330-
0
331-
)
267+
.createCampaign(4, 10, [addresses.mainnet.ConvexVoter], 0)
332268
).to.be.revertedWith("No reward to manage");
333269

334270
await curvePoolBooster.connect(sStrategist).setCampaignId(12);
335271

272+
// manageCampaign with totalRewardAmount != 0 but no balance reverts with "No reward to add"
336273
await expect(
337-
curvePoolBooster.connect(sStrategist).manageTotalRewardAmount(0, 0)
338-
).to.be.revertedWith("No reward to manage");
274+
curvePoolBooster
275+
.connect(sStrategist)
276+
.manageCampaign(ethers.constants.MaxUint256, 0, 0, 0)
277+
).to.be.revertedWith("No reward to add");
339278
});
340279

341280
// --- Rescue ETH and ERC20 ---
342281
it("Should rescue ETH", async () => {
343-
// Deal ETH to pool booster
344-
await sStrategist.sendTransaction({
345-
to: curvePoolBooster.address,
346-
value: parseUnits("1"),
347-
});
282+
// Deal ETH to pool booster using hardhat_setBalance
283+
// (contract no longer has receive() function)
284+
await ethers.provider.send("hardhat_setBalance", [
285+
curvePoolBooster.address,
286+
"0xDE0B6B3A7640000", // 1 ETH in hex
287+
]);
348288

349289
const balanceBefore = await ethers.provider.getBalance(
350290
curvePoolBooster.address

0 commit comments

Comments
 (0)