Skip to content

Commit 4e9c50c

Browse files
change payment logic in readme
1 parent 5c63d89 commit 4e9c50c

File tree

2 files changed

+15
-30
lines changed

2 files changed

+15
-30
lines changed

README.md

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ yarn simulate:staking
413413
- Dispute window: short period after a proposal when disputes are allowed
414414

415415
**Incentives**:
416-
- Reward + bonds flow to the winner; a fixed fee goes to the decider in disputes
416+
- Reward + a bond refund flow to the winner; the loser's bond goes to the decider in disputes
417417

418418
```mermaid
419419
@@ -432,11 +432,11 @@ sequenceDiagram
432432
P->>O: proposeOutcome(assertionId, outcome) + bond
433433
Note over O: Start dispute window
434434
alt No dispute before deadline
435-
O-->>P: Claim undisputed rewards -> reward + proposer bond
435+
O-->>P: Claim undisputed rewards -> reward + bond refund
436436
else Dispute filed in window
437437
D->>O: disputeOutcome(assertionId) + bond
438438
C->>O: settleAssertion(assertionId, resolvedOutcome)
439-
O-->>Winner: claimDisputedReward() -> reward + both bonds - decider fee
439+
O-->>Winner: claimDisputedReward() -> reward + bond refund
440440
end
441441
end
442442
```
@@ -453,7 +453,7 @@ sequenceDiagram
453453

454454
⏳ Then if no one **disputes** the proposal before the dispute window is over then the proposal is considered to be true, and the proposer may claim the reward and their bond. The dispute window should give anyone ample time to submit a dispute.
455455

456-
⚖️ If someone does **dispute** during the dispute window then they must also post a bond equal to the proposer's bond. This kicks the assertion out of any particular timeline and puts it in a state where it is waiting for a decision from the **decider**. Once the decider contract has **settled** the assertion, the winner can claim the reward and both of the bonds that were posted, subtracting a small fee that goes to the decider.
456+
⚖️ If someone does **dispute** during the dispute window then they must also post a bond equal to the proposer's bond. This kicks the assertion out of any particular timeline and puts it in a state where it is waiting for a decision from the **decider**. Once the decider contract has **settled** the assertion, the winner can claim the reward and their posted bond. The decider gets the loser's bond.
457457

458458
🧑‍⚖️ Now, as we mentioned earlier, this oracle has a role called the **decider**. For this example it is just a simple contract that anyone can call to settle disputes. One could imagine in a live oracle you would want something more robust such as a group of people who vote to settle disputes.
459459

@@ -475,7 +475,7 @@ sequenceDiagram
475475

476476
* 📣 This function allows users to assert that an event will have a true/false outcome
477477

478-
* 💸 It should require a minimum reward `msg.value` (`MINIMUM_REWARD`) to be included with the transaction. If it is not enough, revert with `NotEnoughValue`
478+
* 💸 It should require that the reward (`msg.value`) is greater than 0 . If it is not then revert with `NotEnoughValue`
479479

480480
* ⏱️ It should accept 0 for `startTime` and set it to `block.timestamp`
481481

@@ -498,7 +498,7 @@ sequenceDiagram
498498
Here are more granular instructions on setting up the EventAssertion struct:
499499
- asserter should be `msg.sender`
500500
- reward should be `msg.value`
501-
- bond should be `FIXED_BOND`
501+
- bond should be the reward x 2 (You will know why as you understand the economics and game theory)
502502
- startTime = `startTime`
503503
- endTime = `endTime`
504504
- description = `description`
@@ -512,7 +512,7 @@ Here are more granular instructions on setting up the EventAssertion struct:
512512
function assertEvent(string memory description, uint256 startTime, uint256 endTime) external payable returns (uint256) {
513513
uint256 assertionId = nextAssertionId;
514514
nextAssertionId++;
515-
if (msg.value < MINIMUM_REWARD) revert NotEnoughValue();
515+
if (msg.value == 0) revert NotEnoughValue();
516516
517517
// Set default times if not provided
518518
if (startTime == 0) {
@@ -532,7 +532,7 @@ Here are more granular instructions on setting up the EventAssertion struct:
532532
proposedOutcome: false,
533533
resolvedOutcome: false,
534534
reward: msg.value,
535-
bond: FIXED_BOND,
535+
bond: msg.value * 2,
536536
startTime: startTime,
537537
endTime: endTime,
538538
claimed: false,
@@ -716,7 +716,7 @@ Very similar to the last function except this one allows the winner of the dispu
716716

717717
* 📝 Set the `claimed` property on the assertion to `true`
718718

719-
* 💸 Transfer fixed decider fee first (`DECIDER_FEE`), then send remaining reward to the winner - this should be *both* of the bonds (proposer and disputer) plus the reward
719+
* 💸 Transfer the loser's bond to the decider, then send the reward and bond refund to the winner
720720

721721
* 📣 Emit `RewardClaimed`
722722

@@ -725,8 +725,8 @@ Very similar to the last function except this one allows the winner of the dispu
725725

726726
- Validate assertion state: proposed, disputed, winner set, not yet claimed
727727
- Mark as claimed *before* paying to avoid re-entrancy
728-
- Pay `DECIDER_FEE` to `decider`
729-
- Winner receives `(reward + proposerBond + disputerBond - DECIDER_FEE)`
728+
- Pay the losers bond to the `decider`
729+
- Winner receives `(reward + bond)`
730730
- Use safe ETH sending pattern with revert on failure (`TransferFailed`)
731731

732732
<details markdown="1">
@@ -743,10 +743,10 @@ Very similar to the last function except this one allows the winner of the dispu
743743
744744
assertion.claimed = true;
745745
746-
(bool deciderSuccess, ) = payable(decider).call{value: DECIDER_FEE}("");
746+
(bool deciderSuccess, ) = payable(decider).call{value: assertion.bond}("");
747747
if (!deciderSuccess) revert TransferFailed();
748748
749-
uint256 totalReward = (assertion.reward + assertion.bond + assertion.bond) - DECIDER_FEE;
749+
uint256 totalReward = assertion.reward + assertion.bond;
750750
751751
(bool winnerSuccess, ) = payable(assertion.winner).call{value: totalReward}("");
752752
if (!winnerSuccess) revert TransferFailed();
@@ -1115,4 +1115,4 @@ Oracles are fundamental infrastructure for the decentralized web. They enable sm
11151115

11161116
🚀 As you continue your blockchain development journey, you'll encounter many variations and combinations of these patterns. Understanding the fundamental trade-offs will help you choose the right oracle design for your specific use case.
11171117

1118-
🧠 Remember: the best oracle is the one that provides the right balance of security, speed, and cost for your application's needs!
1118+
🧠 Remember: the best oracle is the one that provides the right balance of security, speed, flexibility and cost for your application's needs!

packages/hardhat/test/WhitelistOracle.ts

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,10 @@ import { ethers } from "hardhat";
44
describe("WhitelistOracle", function () {
55
let whitelistOracle;
66
let owner;
7-
let nonOwner;
87
let simpleOracleFactory;
98

109
beforeEach(async function () {
11-
[owner, nonOwner] = await ethers.getSigners();
10+
[owner] = await ethers.getSigners();
1211
const WhitelistOracleFactory = await ethers.getContractFactory("WhitelistOracle");
1312
simpleOracleFactory = await ethers.getContractFactory("SimpleOracle");
1413
whitelistOracle = await WhitelistOracleFactory.deploy();
@@ -30,20 +29,6 @@ describe("WhitelistOracle", function () {
3029
await expect(whitelistOracle.oracles(0)).to.be.reverted;
3130
});
3231

33-
it("Should not allow non-owner to add oracle", async function () {
34-
const oracle = await simpleOracleFactory.deploy();
35-
36-
await expect(whitelistOracle.connect(nonOwner).addOracle(oracle.target)).to.be.revertedWith("Not the owner");
37-
});
38-
39-
it("Should not allow non-owner to remove oracle", async function () {
40-
const oracle = await simpleOracleFactory.deploy();
41-
42-
await whitelistOracle.connect(owner).addOracle(oracle.target);
43-
44-
await expect(whitelistOracle.connect(nonOwner).removeOracle(0)).to.be.revertedWith("Not the owner");
45-
});
46-
4732
it("Should not allow adding duplicate oracle addresses", async function () {
4833
const oracle = await simpleOracleFactory.deploy();
4934

0 commit comments

Comments
 (0)