Skip to content

Commit 5bb82e7

Browse files
Merge pull request #63 from BuidlGuidl/fix/reward-bond-in-oo
fix: reward, bond and decider fee values
2 parents ee543f8 + ed0a197 commit 5bb82e7

File tree

5 files changed

+110
-100
lines changed

5 files changed

+110
-100
lines changed

packages/hardhat/contracts/Optimistic/OptimisticOracle.sol

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,6 @@ contract OptimisticOracle {
3434
}
3535
uint256 public constant MINIMUM_ASSERTION_WINDOW = 3 minutes;
3636
uint256 public constant MINIMUM_DISPUTE_WINDOW = 3 minutes;
37-
uint256 public constant FIXED_BOND = 0.1 ether;
38-
uint256 public constant DECIDER_FEE = 0.2 ether;
39-
uint256 public constant MINIMUM_REWARD = DECIDER_FEE + 0.01 ether;
4037
address public decider;
4138
address public owner;
4239
uint256 public nextAssertionId = 1;
@@ -84,7 +81,7 @@ contract OptimisticOracle {
8481
function assertEvent(string memory description, uint256 startTime, uint256 endTime) external payable returns (uint256) {
8582
uint256 assertionId = nextAssertionId;
8683
nextAssertionId++;
87-
if (msg.value < MINIMUM_REWARD) revert NotEnoughValue();
84+
if (msg.value == 0) revert NotEnoughValue();
8885

8986
// Set default times if not provided
9087
if (startTime == 0) {
@@ -104,7 +101,7 @@ contract OptimisticOracle {
104101
proposedOutcome: false,
105102
resolvedOutcome: false,
106103
reward: msg.value,
107-
bond: FIXED_BOND,
104+
bond: msg.value * 2,
108105
startTime: startTime,
109106
endTime: endTime,
110107
claimed: false,
@@ -191,10 +188,10 @@ contract OptimisticOracle {
191188
assertion.claimed = true;
192189

193190
// Send decider fee
194-
(bool deciderSuccess, ) = payable(decider).call{value: DECIDER_FEE}("");
191+
(bool deciderSuccess, ) = payable(decider).call{value: assertion.bond}("");
195192
if (!deciderSuccess) revert TransferFailed();
196193

197-
uint256 totalReward = (assertion.reward + assertion.bond + assertion.bond) - DECIDER_FEE; // reward + proposer bond + disputer bond - decider fee
194+
uint256 totalReward = assertion.reward + assertion.bond; // reward + proposer bond
198195

199196
// Send reward to winner
200197
(bool winnerSuccess, ) = payable(assertion.winner).call{value: totalReward}("");

packages/hardhat/scripts/runOptimisticBots.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ const createAssertions = async (
3636
otherAccounts: WalletClient[],
3737
accountToAssertionIds: Record<string, bigint[]>,
3838
) => {
39-
const reward = await optimisticOracle.MINIMUM_REWARD();
39+
const minReward = ethers.parseEther("0.01");
4040
let nextAssertionId = await optimisticOracle.nextAssertionId();
4141

4242
for (const account of otherAccounts) {
@@ -47,7 +47,7 @@ const createAssertions = async (
4747
abi: optimisticDeployment.abi,
4848
functionName: "assertEvent",
4949
args: [getRandomQuestion(), 0n, 0n],
50-
value: reward + (1n * 10n ** 18n * BigInt(Math.floor(Math.random() * 100))) / 100n,
50+
value: minReward + (1n * 10n ** 18n * BigInt(Math.floor(Math.random() * 100))) / 100n,
5151
});
5252
console.log(`✅ created assertion ${nextAssertionId}`);
5353

@@ -123,7 +123,6 @@ const disputeAssertions = async (
123123
accountToAssertionIds: Record<string, bigint[]>,
124124
otherAccounts: WalletClient[],
125125
) => {
126-
const bond = await optimisticOracle.FIXED_BOND();
127126
for (const account of otherAccounts) {
128127
const assertionIds = accountToAssertionIds[account.account.address];
129128
for (const assertionId of assertionIds) {
@@ -137,7 +136,7 @@ const disputeAssertions = async (
137136
abi: optimisticDeployment.abi,
138137
functionName: "disputeOutcome",
139138
args: [assertionId],
140-
value: bond,
139+
value: assertion.bond,
141140
});
142141
console.log(`⚔️ disputed assertion ${assertionId}`);
143142
// if disputed, then remove the assertion from the account
@@ -151,7 +150,7 @@ const disputeAssertions = async (
151150
abi: optimisticDeployment.abi,
152151
functionName: "disputeOutcome",
153152
args: [assertionId],
154-
value: bond,
153+
value: assertion.bond,
155154
});
156155
console.log(`⚔️ disputed assertion ${assertionId}`);
157156
// if disputed, then remove the assertion from the account

packages/hardhat/test/OptimisticOracle.test.ts

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,9 @@ describe("OptimisticOracle", function () {
5151
it("Should have correct constants", async function () {
5252
const minimumAssertionWindow = await optimisticOracle.MINIMUM_ASSERTION_WINDOW();
5353
const minimumDisputeWindow = await optimisticOracle.MINIMUM_DISPUTE_WINDOW();
54-
const fixedBond = await optimisticOracle.FIXED_BOND();
55-
const deciderFee = await optimisticOracle.DECIDER_FEE();
5654

5755
expect(minimumAssertionWindow).to.equal(180n); // 3 minutes
5856
expect(minimumDisputeWindow).to.equal(180n); // 3 minutes
59-
expect(fixedBond).to.equal(ethers.parseEther("0.1"));
60-
expect(deciderFee).to.equal(ethers.parseEther("0.2"));
6157
});
6258

6359
it("Should start with nextAssertionId at 1", async function () {
@@ -107,7 +103,7 @@ describe("OptimisticOracle", function () {
107103

108104
it("Should reject assertions with insufficient reward", async function () {
109105
const description = "Will Bitcoin reach $1m by end of 2026?";
110-
const insufficientReward = ethers.parseEther("0.1"); // Less than minimum
106+
const insufficientReward = ethers.parseEther("0.0");
111107

112108
await expect(
113109
optimisticOracle.connect(asserter).assertEvent(description, 0, 0, { value: insufficientReward }),
@@ -134,7 +130,7 @@ describe("OptimisticOracle", function () {
134130
});
135131

136132
it("Should allow proposing outcomes with correct bond", async function () {
137-
const bond = await optimisticOracle.FIXED_BOND();
133+
const bond = reward * 2n;
138134
const outcome = true;
139135

140136
const tx = await optimisticOracle.connect(proposer).proposeOutcome(assertionId, outcome, { value: bond });
@@ -156,7 +152,7 @@ describe("OptimisticOracle", function () {
156152
});
157153

158154
it("Should reject duplicate proposals", async function () {
159-
const bond = await optimisticOracle.FIXED_BOND();
155+
const bond = reward * 2n;
160156
const outcome = true;
161157

162158
await optimisticOracle.connect(proposer).proposeOutcome(assertionId, outcome, { value: bond });
@@ -183,12 +179,12 @@ describe("OptimisticOracle", function () {
183179
const parsedEvent = optimisticOracle.interface.parseLog(event as any);
184180
assertionId = parsedEvent!.args[0];
185181

186-
const bond = await optimisticOracle.FIXED_BOND();
182+
const bond = reward * 2n;
187183
await optimisticOracle.connect(proposer).proposeOutcome(assertionId, true, { value: bond });
188184
});
189185

190186
it("Should allow disputing outcomes with correct bond", async function () {
191-
const bond = await optimisticOracle.FIXED_BOND();
187+
const bond = reward * 2n;
192188

193189
const tx = await optimisticOracle.connect(disputer).disputeOutcome(assertionId, { value: bond });
194190

@@ -212,14 +208,14 @@ describe("OptimisticOracle", function () {
212208
await ethers.provider.send("evm_increaseTime", [181]); // 3 minutes + 1 second
213209
await ethers.provider.send("evm_mine");
214210

215-
const bond = await optimisticOracle.FIXED_BOND();
211+
const bond = reward * 2n;
216212
await expect(
217213
optimisticOracle.connect(disputer).disputeOutcome(assertionId, { value: bond }),
218214
).to.be.revertedWithCustomError(optimisticOracle, "InvalidTime");
219215
});
220216

221217
it("Should reject duplicate disputes", async function () {
222-
const bond = await optimisticOracle.FIXED_BOND();
218+
const bond = reward * 2n;
223219
await optimisticOracle.connect(disputer).disputeOutcome(assertionId, { value: bond });
224220

225221
await expect(
@@ -244,7 +240,7 @@ describe("OptimisticOracle", function () {
244240
const parsedEvent = optimisticOracle.interface.parseLog(event as any);
245241
assertionId = parsedEvent!.args[0];
246242

247-
const bond = await optimisticOracle.FIXED_BOND();
243+
const bond = reward * 2n;
248244
await optimisticOracle.connect(proposer).proposeOutcome(assertionId, true, { value: bond });
249245
});
250246

@@ -258,8 +254,8 @@ describe("OptimisticOracle", function () {
258254
const receipt = await tx.wait();
259255
const finalBalance = await ethers.provider.getBalance(proposer.address);
260256

261-
// Check that proposer received the reward (reward + bond - decider fee - gas costs)
262-
const expectedReward = reward + (await optimisticOracle.FIXED_BOND());
257+
// Check that proposer received the reward (reward + bond - gas costs)
258+
const expectedReward = reward + reward * 2n;
263259
const gasCost = receipt!.gasUsed * receipt!.gasPrice!;
264260
expect(finalBalance - initialBalance + gasCost).to.equal(expectedReward);
265261
});
@@ -272,7 +268,7 @@ describe("OptimisticOracle", function () {
272268
});
273269

274270
it("Should reject claiming disputed assertions", async function () {
275-
const bond = await optimisticOracle.FIXED_BOND();
271+
const bond = reward * 2n;
276272
await optimisticOracle.connect(disputer).disputeOutcome(assertionId, { value: bond });
277273

278274
await expect(optimisticOracle.connect(proposer).claimUndisputedReward(assertionId)).to.be.revertedWithCustomError(
@@ -310,7 +306,7 @@ describe("OptimisticOracle", function () {
310306
const parsedEvent = optimisticOracle.interface.parseLog(event as any);
311307
assertionId = parsedEvent!.args[0];
312308

313-
const bond = await optimisticOracle.FIXED_BOND();
309+
const bond = reward * 2n;
314310
await optimisticOracle.connect(proposer).proposeOutcome(assertionId, true, { value: bond });
315311
await optimisticOracle.connect(disputer).disputeOutcome(assertionId, { value: bond });
316312
});
@@ -324,9 +320,8 @@ describe("OptimisticOracle", function () {
324320
const receipt = await tx.wait();
325321
const finalBalance = await ethers.provider.getBalance(proposer.address);
326322

327-
// Check that proposer received the reward (reward + 2*bond - decider fee - gas costs)
328-
const expectedReward =
329-
reward + (await optimisticOracle.FIXED_BOND()) * 2n - (await optimisticOracle.DECIDER_FEE());
323+
// Check that proposer received the reward (reward + bond - gas costs)
324+
const expectedReward = reward * 3n;
330325
const gasCost = receipt!.gasUsed * receipt!.gasPrice!;
331326
expect(finalBalance - initialBalance + gasCost).to.equal(expectedReward);
332327
});
@@ -341,8 +336,7 @@ describe("OptimisticOracle", function () {
341336
const finalBalance = await ethers.provider.getBalance(disputer.address);
342337

343338
// Check that disputer received the reward
344-
const expectedReward =
345-
reward + (await optimisticOracle.FIXED_BOND()) * 2n - (await optimisticOracle.DECIDER_FEE());
339+
const expectedReward = reward * 3n;
346340
const gasCost = receipt!.gasUsed * receipt!.gasPrice!;
347341
expect(finalBalance - initialBalance + gasCost).to.equal(expectedReward);
348342
});
@@ -398,7 +392,7 @@ describe("OptimisticOracle", function () {
398392
});
399393

400394
it("Should reject refund claiming for assertions with proposals", async function () {
401-
const bond = await optimisticOracle.FIXED_BOND();
395+
const bond = reward * 2n;
402396
await optimisticOracle.connect(proposer).proposeOutcome(assertionId, true, { value: bond });
403397

404398
await expect(optimisticOracle.connect(asserter).claimRefund(assertionId)).to.be.revertedWithCustomError(
@@ -436,7 +430,7 @@ describe("OptimisticOracle", function () {
436430
const parsedEvent = optimisticOracle.interface.parseLog(event as any);
437431
assertionId = parsedEvent!.args[0];
438432

439-
const bond = await optimisticOracle.FIXED_BOND();
433+
const bond = reward * 2n;
440434
await optimisticOracle.connect(proposer).proposeOutcome(assertionId, true, { value: bond });
441435
await optimisticOracle.connect(disputer).disputeOutcome(assertionId, { value: bond });
442436
});
@@ -471,7 +465,7 @@ describe("OptimisticOracle", function () {
471465
const newParsedEvent = optimisticOracle.interface.parseLog(newEvent as any);
472466
const newAssertionId = newParsedEvent!.args[0];
473467

474-
const bond = await optimisticOracle.FIXED_BOND();
468+
const bond = reward * 2n;
475469
await optimisticOracle.connect(proposer).proposeOutcome(newAssertionId, true, { value: bond });
476470

477471
const resolvedOutcome = true;
@@ -503,7 +497,7 @@ describe("OptimisticOracle", function () {
503497
expect(state).to.equal(State.Asserted); // Asserted
504498

505499
// Proposed state
506-
const bond = await optimisticOracle.FIXED_BOND();
500+
const bond = reward * 2n;
507501
await optimisticOracle.connect(proposer).proposeOutcome(assertionId, true, { value: bond });
508502
state = await optimisticOracle.getState(assertionId);
509503
expect(state).to.equal(State.Proposed); // Proposed
@@ -531,7 +525,7 @@ describe("OptimisticOracle", function () {
531525
const parsedEvent = optimisticOracle.interface.parseLog(event as any);
532526
const assertionId = parsedEvent!.args[0];
533527

534-
const bond = await optimisticOracle.FIXED_BOND();
528+
const bond = reward * 2n;
535529
await optimisticOracle.connect(proposer).proposeOutcome(assertionId, true, { value: bond });
536530

537531
// Fast forward time past dispute window
@@ -578,7 +572,7 @@ describe("OptimisticOracle", function () {
578572
if (!parsedEvent) throw new Error("Event not found");
579573
const assertionId = parsedEvent.args[0];
580574

581-
const bond = await optimisticOracle.FIXED_BOND();
575+
const bond = reward * 2n;
582576
await expect(
583577
optimisticOracle.connect(proposer).proposeOutcome(assertionId, true, { value: bond }),
584578
).to.be.revertedWithCustomError(optimisticOracle, "InvalidTime");
@@ -602,7 +596,7 @@ describe("OptimisticOracle", function () {
602596
await ethers.provider.send("evm_increaseTime", [201]);
603597
await ethers.provider.send("evm_mine");
604598

605-
const bond = await optimisticOracle.FIXED_BOND();
599+
const bond = reward * 2n;
606600
await expect(
607601
optimisticOracle.connect(proposer).proposeOutcome(assertionId, true, { value: bond }),
608602
).to.be.revertedWithCustomError(optimisticOracle, "InvalidTime");
@@ -622,7 +616,7 @@ describe("OptimisticOracle", function () {
622616
if (!parsedEvent) throw new Error("Event not found");
623617
const assertionId = parsedEvent.args[0];
624618

625-
const bond = await optimisticOracle.FIXED_BOND();
619+
const bond = reward * 2n;
626620

627621
// Before startTime - should fail
628622
await expect(

packages/nextjs/components/oracle/optimistic/SubmitAssertionButton.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import { useGlobalState } from "~~/services/store/store";
1010
import { getRandomQuestion } from "~~/utils/helpers";
1111
import { notification } from "~~/utils/scaffold-eth";
1212

13-
const MINIMUM_REWARD = 0.21;
1413
const MINIMUM_ASSERTION_WINDOW = 3;
1514

1615
const getStartTimestamp = (timestamp: bigint, startInMinutes: string) => {
@@ -56,8 +55,8 @@ const SubmitAssertionModal = ({ isOpen, onClose }: SubmitAssertionModalProps) =>
5655
return;
5756
}
5857

59-
if (Number(reward) < MINIMUM_REWARD) {
60-
notification.error(`Reward must be at least ${MINIMUM_REWARD} ETH`);
58+
if (Number(reward) === 0) {
59+
notification.error(`Reward must be greater than 0 ETH`);
6160
return;
6261
}
6362

@@ -176,7 +175,7 @@ const SubmitAssertionModal = ({ isOpen, onClose }: SubmitAssertionModalProps) =>
176175
</label>
177176
<IntegerInput
178177
name="reward"
179-
placeholder={`Minimum ${MINIMUM_REWARD} ETH`}
178+
placeholder={`0.01 ETH`}
180179
value={reward}
181180
onChange={newValue => setReward(newValue)}
182181
disableMultiplyBy1e18

0 commit comments

Comments
 (0)