Skip to content

Commit 610a043

Browse files
authored
disputes: update fisherman deposit to be fixed amount (#168)
1 parent 6bc2c26 commit 610a043

File tree

7 files changed

+102
-51
lines changed

7 files changed

+102
-51
lines changed

DEPLOYMENT.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
## Deploying the Solidity Smart Contracts via Truffle
22

33
`/migrations/2_deploy_contracts.js` contains the parameters needed to deploy the contracts. Please edit these params as you see fit.
4+
45
```
56
const initialSupply = 1000000, // total supply of Graph Tokens at time of deployment
67
minimumCurationStakingAmount = 100, // minimum amount allowed to be staked by Market Curators
78
defaultReserveRatio = 500000, // reserve ratio (percent as PPM)
89
minimumIndexingStakingAmount = 100, // minimum amount allowed to be staked by Indexing Nodes
910
maximumIndexers = 10, // maximum number of Indexing Nodes staked higher than stake to consider
10-
slashingPercent = 10, // percent of stake to slash in successful dispute
11+
slashingPercentage = 10, // percent of stake to slash in successful dispute
1112
thawingPeriod = 60 * 60 * 24 * 7, // amount of seconds to wait until indexer can finish stake logout
1213
multiSigRequiredVote = 0, // votes required (setting a required amount here will override a formula used later)
1314
multiSigOwners = [] // add addresses of the owners of the multisig contract here
1415
```
1516

16-
The `MultiSigWallet` contract is deployed first in order to retain its address for use in deploying the remaining contracts.
17+
The `MultiSigWallet` contract is deployed first in order to retain its address for use in deploying the remaining contracts.
1718

1819
The `Staking` contract requires both the address of the `MultiSigWallet` and the `GraphToken`.
1920

contracts/DisputeManager.sol

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,12 @@ contract DisputeManager is Governed {
8282
// The arbitrator is solely in control of arbitrating disputes
8383
address public arbitrator;
8484

85-
// Percent of stake to slash in successful dispute
85+
// Minimum deposit required to create a Dispute
86+
uint256 public minimumDeposit;
87+
88+
// Percentage of index node stake to slash in successful dispute
8689
// Parts per million. (Allows for 4 decimal points, 999,999 = 99.9999%)
87-
uint256 public slashingPercent;
90+
uint256 public slashingPercentage;
8891

8992
// Graph Token address
9093
GraphToken public token;
@@ -137,20 +140,23 @@ contract DisputeManager is Governed {
137140
* @param _token <address> - Address of the Graph Protocol token
138141
* @param _arbitrator <address> - Arbitrator role
139142
* @param _staking <address> - Address of the staking contract used for slashing
140-
* @param _slashingPercent <uint256> - Percent of stake the fisherman gets on slashing (in PPM)
143+
* @param _slashingPercentage <uint256> - Percent of stake the fisherman gets on slashing (in PPM)
144+
* @param _minimumDeposit <uint256> - Minimum deposit required to create a Dispute
141145
*/
142146
constructor(
143147
address _governor,
144148
address _token,
145149
address _arbitrator,
146150
address _staking,
147-
uint256 _slashingPercent
151+
uint256 _slashingPercentage,
152+
uint256 _minimumDeposit
148153
) public Governed(_governor) {
149154
_setArbitrator(_arbitrator);
150155
token = GraphToken(_token);
151156
staking = Staking(_staking);
152157

153-
slashingPercent = _slashingPercent;
158+
minimumDeposit = _minimumDeposit;
159+
slashingPercentage = _slashingPercentage;
154160

155161
// EIP-712 domain separator
156162
DOMAIN_SEPARATOR = keccak256(
@@ -180,7 +186,7 @@ contract DisputeManager is Governed {
180186
* @return <uint256> - Percentage of validator's stake to be considered a reward
181187
*/
182188
function getRewardForStake(uint256 _value) public view returns (uint256) {
183-
return slashingPercent.mul(_value).div(MAX_PPM); // slashingPercent is in PPM
189+
return slashingPercentage.mul(_value).div(MAX_PPM); // slashingPercentage is in PPM
184190
}
185191

186192
/**
@@ -229,26 +235,38 @@ contract DisputeManager is Governed {
229235
arbitrator = _arbitrator;
230236
}
231237

238+
/**
239+
* @dev Set the minimum deposit required to create a dispute
240+
* @notice Update the minimum deposit to `_minimumDeposit` Graph Tokens
241+
* @param _minimumDeposit <uint256> - The minimum deposit in Graph Tokens
242+
*/
243+
function setMinimumDeposit(uint256 _minimumDeposit)
244+
external
245+
onlyGovernance
246+
{
247+
minimumDeposit = _minimumDeposit;
248+
}
249+
232250
/**
233251
* @dev Set the percent that the fisherman gets when slashing occurs
234-
* @notice Update the slashing percent to `_slashingPercent`
235-
* @param _slashingPercent <uint256> - Slashing percent
252+
* @notice Update the slashing percent to `_slashingPercentage`
253+
* @param _slashingPercentage <uint256> - Slashing percentage
236254
*/
237-
function setSlashingPercent(uint256 _slashingPercent)
255+
function setSlashingPercentage(uint256 _slashingPercentage)
238256
external
239257
onlyGovernance
240258
{
241-
// Slashing Percent must be within 0% to 100% (inclusive)
259+
// Must be within 0% to 100% (inclusive)
242260
require(
243-
_slashingPercent >= 0,
244-
"Slashing percent must above or equal to 0"
261+
_slashingPercentage >= 0,
262+
"Slashing percentage must above or equal to 0"
245263
);
246264
require(
247-
_slashingPercent <= MAX_PPM,
248-
"Slashing percent must be below or equal to MAX_PPM"
265+
_slashingPercentage <= MAX_PPM,
266+
"Slashing percentage must be below or equal to MAX_PPM"
249267
);
250268

251-
slashingPercent = _slashingPercent;
269+
slashingPercentage = _slashingPercentage;
252270
}
253271

254272
/**
@@ -307,7 +325,7 @@ contract DisputeManager is Governed {
307325
delete disputes[_disputeID]; // Re-entrancy protection
308326

309327
// Have staking slash the index node and reward the fisherman
310-
// Give the fisherman a reward equal to the slashingPercent of the indexer's stake
328+
// Give the fisherman a reward equal to the slashingPercentage of the indexer's stake
311329
uint256 stake = staking.getIndexingNodeStake(
312330
dispute.subgraphID,
313331
dispute.indexNode
@@ -422,9 +440,9 @@ contract DisputeManager is Governed {
422440
"Dispute has no stake on the subgraph by the indexer node"
423441
);
424442

425-
// Ensure that fisherman has posted at least that amount
443+
// Ensure that fisherman has staked at least that amount
426444
require(
427-
_deposit >= getRewardForStake(stake),
445+
_deposit >= minimumDeposit,
428446
"Dispute deposit under minimum required"
429447
);
430448

graphProtocol.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,11 @@ module.exports = (options = {}) => {
107107
}
108108

109109
/**
110-
* @dev Getter for `slashingPercent`
111-
* @returns {Number} Slashing percent
110+
* @dev Getter for `slashingPercentage`
111+
* @returns {Number} Slashing percentage
112112
*/
113-
static slashingPercent() {
114-
return Staking.slashingPercent()
113+
static slashingPercentage() {
114+
return Staking.slashingPercentage()
115115
}
116116

117117
/**

migrations/2_deploy_contracts.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const minimumIndexingStakingAmount = new BN('100000000000000000000')
2222
// maximum number of Indexing Nodes staked higher than stake to consider
2323
const maximumIndexers = 10
2424
// percent of stake to slash in successful dispute
25-
// const slashingPercent = 10
25+
// const slashingPercentage = 10
2626
// amount of seconds to wait until indexer can finish stake logout
2727
const thawingPeriod = 60 * 60 * 24 * 7
2828
// votes required (setting a required amount here will override a formula used later)

test/disputes.test.js

Lines changed: 49 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -83,35 +83,64 @@ contract(
8383
)
8484
})
8585

86-
it('should set `slashingPercent`', async function() {
86+
it('should set `slashingPercentage`', async function() {
87+
const slashingPercentage = helpers.stakingConstants.slashingPercentage
88+
8789
// Set right in the constructor
8890
expect(
89-
await this.disputeManager.slashingPercent(),
90-
).to.be.bignumber.equal(
91-
helpers.stakingConstants.slashingPercent.toString(),
92-
)
93-
94-
// Can set if allowed
95-
await this.disputeManager.setSlashingPercent(0, { from: governor })
96-
await this.disputeManager.setSlashingPercent(1, { from: governor })
97-
await this.disputeManager.setSlashingPercent(
98-
helpers.stakingConstants.slashingPercent,
99-
{ from: governor },
100-
)
91+
await this.disputeManager.slashingPercentage(),
92+
).to.be.bignumber.equal(slashingPercentage.toString())
93+
94+
// Set new value
95+
await this.disputeManager.setSlashingPercentage(0, { from: governor })
96+
await this.disputeManager.setSlashingPercentage(1, { from: governor })
97+
await this.disputeManager.setSlashingPercentage(slashingPercentage, {
98+
from: governor,
99+
})
101100
})
102101

103-
it('reject set `slashingPercent` if out of bounds', async function() {
102+
it('reject set `slashingPercentage` if out of bounds', async function() {
104103
await expectRevert(
105-
this.disputeManager.setSlashingPercent(MAX_PPM + 1, {
104+
this.disputeManager.setSlashingPercentage(MAX_PPM + 1, {
106105
from: governor,
107106
}),
108-
'Slashing percent must be below or equal to MAX_PPM',
107+
'Slashing percentage must be below or equal to MAX_PPM',
109108
)
110109
})
111110

112-
it('reject set `slashingPercent` if not allowed', async function() {
111+
it('reject set `slashingPercentage` if not allowed', async function() {
113112
await expectRevert(
114-
this.disputeManager.setSlashingPercent(50, { from: other }),
113+
this.disputeManager.setSlashingPercentage(50, { from: other }),
114+
'Only Governor can call',
115+
)
116+
})
117+
it('should set `minimumDeposit`', async function() {
118+
const minimumDeposit =
119+
helpers.stakingConstants.minimumDisputeDepositAmount
120+
const newMinimumDeposit = web3.utils.toBN(1)
121+
122+
// Set right in the constructor
123+
expect(
124+
await this.disputeManager.minimumDeposit(),
125+
).to.be.bignumber.equal(minimumDeposit)
126+
127+
// Set new value
128+
await this.disputeManager.setMinimumDeposit(newMinimumDeposit, {
129+
from: governor,
130+
})
131+
expect(
132+
await this.disputeManager.minimumDeposit(),
133+
).to.be.bignumber.equal(newMinimumDeposit)
134+
})
135+
136+
it('reject set `minimumDeposit` if not allowed', async function() {
137+
const minimumDeposit =
138+
helpers.stakingConstants.minimumDisputeDepositAmount
139+
140+
await expectRevert(
141+
this.disputeManager.setMinimumDeposit(minimumDeposit, {
142+
from: other,
143+
}),
115144
'Only Governor can call',
116145
)
117146
})
@@ -132,7 +161,7 @@ contract(
132161
it('should calculate the reward for a stake', async function() {
133162
const stakedAmount = 1000
134163
const trueReward =
135-
(helpers.stakingConstants.slashingPercent * stakedAmount) / MAX_PPM
164+
(helpers.stakingConstants.slashingPercentage * stakedAmount) / MAX_PPM
136165
const funcReward = await this.disputeManager.getRewardForStake(
137166
stakedAmount,
138167
)
@@ -219,9 +248,7 @@ contract(
219248
})
220249

221250
// Minimum deposit a fisherman is required to do should be >= reward
222-
const minimumDeposit = await this.disputeManager.getRewardForStake(
223-
this.indexNodeStake,
224-
)
251+
const minimumDeposit = await this.disputeManager.minimumDeposit()
225252
const belowMinimumDeposit = minimumDeposit.sub(web3.utils.toBN(1))
226253

227254
// Create invalid dispute as deposit is below minimum

test/lib/deployment.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,17 @@ function deployDisputeManagerContract(
4040
staking,
4141
params,
4242
) {
43-
const slashingPercent = helpers.stakingConstants.slashingPercent
43+
const slashingPercentage = helpers.stakingConstants.slashingPercentage
44+
const minimumDisputeDepositAmount =
45+
helpers.stakingConstants.minimumDisputeDepositAmount
4446

4547
return DisputeManager.new(
4648
owner,
4749
graphToken,
4850
arbitrator,
4951
staking,
50-
slashingPercent,
52+
slashingPercentage,
53+
minimumDisputeDepositAmount,
5154
params,
5255
)
5356
}

test/lib/testHelpers.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,11 +297,13 @@ module.exports = {
297297
stakingConstants: {
298298
// 100 * 10^18 minimum amount allowed to be staked by Market Curators
299299
minimumCurationStakingAmount: new BN('100000000000000000000'),
300-
// 100 * 10^18 minimum amount allowed to be staked by Market Curators
300+
// 100 * 10^18 minimum amount allowed to be staked by Indexers
301301
minimumIndexingStakingAmount: new BN('100000000000000000000'),
302+
// 100 * 10^18 minimum amount required as deposit to create a Dispute
303+
minimumDisputeDepositAmount: new BN('100000000000000000000'),
302304
defaultReserveRatio: 500000,
303305
maximumIndexers: 10,
304-
slashingPercent: 1000,
306+
slashingPercentage: 1000,
305307
thawingPeriod: 60 * 60 * 24 * 7, // In seconds
306308
thawingPeriodSimple: 0,
307309
},

0 commit comments

Comments
 (0)