Skip to content

Commit 3fd43b5

Browse files
authored
curation: refactor variable names and balance functions, fix tokens to share formula (#173)
1 parent e642ad3 commit 3fd43b5

File tree

2 files changed

+142
-108
lines changed

2 files changed

+142
-108
lines changed

contracts/Curation.sol

Lines changed: 112 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,10 @@ contract Curation is Governed, BancorFormula {
2020
// -- Curation --
2121

2222
struct Subgraph {
23-
uint256 reserveRatio;
24-
uint256 totalTokens;
25-
uint256 totalShares;
26-
}
27-
28-
struct SubgraphCurator {
29-
uint256 totalShares;
23+
uint256 reserveRatio; // Ratio for the bonding curve
24+
uint256 tokens; // Tokens that constitute the subgraph reserve
25+
uint256 shares; // Shares issued for this subgraph
26+
mapping(address => uint256) curatorShares;
3027
}
3128

3229
// 100% in parts per million
@@ -53,7 +50,6 @@ contract Curation is Governed, BancorFormula {
5350

5451
// Subgraphs and curators mapping
5552
mapping(bytes32 => Subgraph) public subgraphs;
56-
mapping(bytes32 => mapping(address => SubgraphCurator)) public subgraphCurators;
5753

5854
// Address of a party that will distribute fees to subgraph reserves
5955
address public distributor;
@@ -66,13 +62,13 @@ contract Curation is Governed, BancorFormula {
6662
event CuratorStakeUpdated(
6763
address indexed curator,
6864
bytes32 indexed subgraphID,
69-
uint256 totalShares
65+
uint256 shares
7066
);
7167

7268
event SubgraphStakeUpdated(
7369
bytes32 indexed subgraphID,
74-
uint256 totalShares,
75-
uint256 totalTokens
70+
uint256 shares,
71+
uint256 tokens
7672
);
7773

7874
/**
@@ -193,7 +189,7 @@ contract Curation is Governed, BancorFormula {
193189
}
194190

195191
// Any other source address means they are staking
196-
stake(subgraphID, _from, _value);
192+
stake(_from, subgraphID, _value);
197193
return true;
198194
}
199195

@@ -207,43 +203,28 @@ contract Curation is Governed, BancorFormula {
207203
address curator = msg.sender;
208204
Subgraph storage subgraph = subgraphs[_subgraphID];
209205

210-
211-
SubgraphCurator storage subgraphCurator
212-
= subgraphCurators[_subgraphID][curator];
213-
214206
require(_shares > 0, "Cannot unstake zero shares");
215207
require(
216-
subgraphCurator.totalShares >= _shares,
208+
subgraph.curatorShares[curator] >= _shares,
217209
"Cannot unstake more shares than you own"
218210
);
219211

220212
// Obtain the amount of tokens to refund based on returned shares
221213
uint256 tokensToRefund = subgraphSharesToTokens(_subgraphID, _shares);
222-
uint256 tokensLeft = subgraph.totalTokens.sub(tokensToRefund);
214+
215+
// Update balance
216+
decreaseBalance(curator, _subgraphID, tokensToRefund, _shares);
223217

224218
// Ensure we are not under minimum required stake
225219
require(
226-
tokensLeft >= minimumCurationStake || tokensLeft == 0,
220+
subgraph.tokens >= minimumCurationStake || subgraph.tokens == 0,
227221
"Cannot unstake below minimum required stake for subgraph"
228222
);
229223

230-
// Update subgraph balances
231-
subgraph.totalTokens = tokensLeft;
232-
subgraph.totalShares = subgraph.totalShares.sub(_shares);
233-
234-
// Update subgraph/curator balances
235-
subgraphCurator.totalShares = subgraphCurator.totalShares.sub(_shares);
236-
237-
// Update global tokens balance
238-
totalTokens = totalTokens.sub(tokensToRefund);
239-
240224
// Delete if left without stakes
241-
if (subgraph.totalTokens == 0) {
225+
if (subgraph.tokens == 0) {
242226
delete subgraphs[_subgraphID];
243227
}
244-
if (subgraphCurator.totalShares == 0) {
245-
delete subgraphCurators[_subgraphID][curator];
246-
}
247228

248229
// Return the tokens to the curator
249230
require(
@@ -254,12 +235,12 @@ contract Curation is Governed, BancorFormula {
254235
emit CuratorStakeUpdated(
255236
curator,
256237
_subgraphID,
257-
subgraphCurator.totalShares
238+
subgraph.curatorShares[curator]
258239
);
259240
emit SubgraphStakeUpdated(
260241
_subgraphID,
261-
subgraph.totalShares,
262-
subgraph.totalTokens
242+
subgraph.shares,
243+
subgraph.tokens
263244
);
264245
}
265246

@@ -269,7 +250,21 @@ contract Curation is Governed, BancorFormula {
269250
* @return <bool> True if the subgraph is curated
270251
*/
271252
function isSubgraphCurated(bytes32 _subgraphID) public view returns (bool) {
272-
return subgraphs[_subgraphID].totalTokens > 0;
253+
return subgraphs[_subgraphID].tokens > 0;
254+
}
255+
256+
/**
257+
* @dev Get the number of shares a curator has on a particular subgraph
258+
* @param _curator <address> Curator owning the shares
259+
* @param _subgraphID <uint256> Subgraph of issued shares
260+
* @return <uint256> Number of subgraph shares issued for a curator
261+
*/
262+
function getCuratorShares(address _curator, bytes32 _subgraphID)
263+
public
264+
view
265+
returns (uint256)
266+
{
267+
return subgraphs[_subgraphID].curatorShares[_curator];
273268
}
274269

275270
/**
@@ -283,20 +278,22 @@ contract Curation is Governed, BancorFormula {
283278
view
284279
returns (uint256)
285280
{
286-
// handle initialization of bonding curve
281+
// Handle initialization of bonding curve
282+
uint256 tokens = _tokens;
287283
uint256 shares = 0;
288284
Subgraph memory subgraph = subgraphs[_subgraphID];
289-
if (subgraph.totalTokens == 0) {
285+
if (subgraph.tokens == 0) {
290286
subgraph = getDefaultSubgraph();
291-
shares = 1;
287+
tokens = tokens.sub(subgraph.tokens);
288+
shares = subgraph.shares;
292289
}
293290

294291
return
295292
calculatePurchaseReturn(
296-
subgraph.totalShares,
297-
subgraph.totalTokens,
293+
subgraph.shares,
294+
subgraph.tokens,
298295
uint32(subgraph.reserveRatio),
299-
_tokens
296+
tokens
300297
) + shares;
301298
}
302299

@@ -313,17 +310,17 @@ contract Curation is Governed, BancorFormula {
313310
{
314311
Subgraph memory subgraph = subgraphs[_subgraphID];
315312
require(
316-
subgraph.totalTokens > 0,
313+
subgraph.tokens > 0,
317314
"Subgraph must be curated to perform calculations"
318315
);
319316
require(
320-
subgraph.totalShares >= _shares,
317+
subgraph.shares >= _shares,
321318
"Shares must be above or equal to total shares issued for the subgraph"
322319
);
323320
return
324321
calculateSaleReturn(
325-
subgraph.totalShares,
326-
subgraph.totalTokens,
322+
subgraph.shares,
323+
subgraph.tokens,
327324
uint32(subgraph.reserveRatio),
328325
_shares
329326
);
@@ -334,6 +331,7 @@ contract Curation is Governed, BancorFormula {
334331
* @return <Subgraph> An initialized subgraph
335332
*/
336333
function getDefaultSubgraph() private view returns (Subgraph memory) {
334+
// Note: The first share costs minimumCurationStake amount of tokens
337335
Subgraph memory subgraph = Subgraph(
338336
defaultReserveRatio,
339337
minimumCurationStake,
@@ -342,47 +340,93 @@ contract Curation is Governed, BancorFormula {
342340
return subgraph;
343341
}
344342

343+
/**
344+
* @dev Update balances after buy of shares and deposit of tokens
345+
* @param _curator <address> - Curator
346+
* @param _subgraphID <bytes32> - Subgraph
347+
* @param _tokens <uint256> - Amount of tokens
348+
* @param _shares <uint256> - Amount of shares
349+
*/
350+
function increaseBalance(
351+
address _curator,
352+
bytes32 _subgraphID,
353+
uint256 _tokens,
354+
uint256 _shares
355+
) internal {
356+
// Update subgraph balance
357+
Subgraph storage subgraph = subgraphs[_subgraphID];
358+
subgraph.tokens = subgraph.tokens.add(_tokens);
359+
subgraph.shares = subgraph.shares.add(_shares);
360+
subgraph.curatorShares[_curator] = subgraph.curatorShares[_curator].add(
361+
_shares
362+
);
363+
364+
// Update global balance
365+
totalTokens = totalTokens.add(_tokens);
366+
}
367+
368+
/**
369+
* @dev Update balances after sell of shares and return of tokens
370+
* @param _curator <address> - Curator
371+
* @param _subgraphID <bytes32> - Subgraph
372+
* @param _tokens <uint256> - Amount of tokens
373+
* @param _shares <uint256> - Amount of shares
374+
*/
375+
function decreaseBalance(
376+
address _curator,
377+
bytes32 _subgraphID,
378+
uint256 _tokens,
379+
uint256 _shares
380+
) internal {
381+
// Update subgraph balance
382+
Subgraph storage subgraph = subgraphs[_subgraphID];
383+
subgraph.tokens = subgraph.tokens.sub(_tokens);
384+
subgraph.shares = subgraph.shares.sub(_shares);
385+
subgraph.curatorShares[_curator] = subgraph.curatorShares[_curator].sub(
386+
_shares
387+
);
388+
389+
// Update global balance
390+
totalTokens = totalTokens.sub(_tokens);
391+
}
392+
345393
/**
346394
* @dev Assign Graph Tokens received from distributor to the subgraph reserve
347395
* @param _subgraphID <bytes32> - Subgraph where funds should be allocated as reserves
348-
* @param _amount <uint256> - Amount of Graph Tokens to add to reserves
396+
* @param _tokens <uint256> - Amount of Graph Tokens to add to reserves
349397
*/
350-
function collect(bytes32 _subgraphID, uint256 _amount) private {
398+
function collect(bytes32 _subgraphID, uint256 _tokens) private {
351399
require(
352400
isSubgraphCurated(_subgraphID),
353401
"Subgraph must be curated to collect fees"
354402
);
355403

356404
// Collect new funds to reserve
357405
Subgraph storage subgraph = subgraphs[_subgraphID];
358-
subgraph.totalTokens = subgraph.totalTokens.add(_amount);
406+
subgraph.tokens = subgraph.tokens.add(_tokens);
359407

360408
// Update global tokens balance
361-
totalTokens = totalTokens.add(_amount);
409+
totalTokens = totalTokens.add(_tokens);
362410

363411
emit SubgraphStakeUpdated(
364412
_subgraphID,
365-
subgraph.totalShares,
366-
subgraph.totalTokens
413+
subgraph.shares,
414+
subgraph.tokens
367415
);
368416
}
369417

370418
/**
371419
* @dev Stake Graph Tokens for Market Curation by subgraphID
372420
* @param _subgraphID <bytes32> - Subgraph ID the Curator is staking Graph Tokens for
373421
* @param _curator <address> - Address of Staking party
374-
* @param _amount <uint256> - Amount of Graph Tokens to be staked
422+
* @param _tokens <uint256> - Amount of Graph Tokens to be staked
375423
*/
376-
function stake(bytes32 _subgraphID, address _curator, uint256 _amount)
424+
function stake(address _curator, bytes32 _subgraphID, uint256 _tokens)
377425
private
378426
{
379-
uint256 tokens = _amount;
427+
uint256 tokens = _tokens;
380428
Subgraph storage subgraph = subgraphs[_subgraphID];
381429

382-
383-
SubgraphCurator storage subgraphCurator
384-
= subgraphCurators[_subgraphID][_curator];
385-
386430
// If this subgraph hasn't been curated before then initialize the curve
387431
// Sets the initial slope for the curve, controlled by minimumCurationStake
388432
if (!isSubgraphCurated(_subgraphID)) {
@@ -393,14 +437,14 @@ contract Curation is Governed, BancorFormula {
393437
);
394438

395439
// Initialize subgraph
396-
// Note: The first share costs minimumCurationStake amount of tokens
397440
subgraphs[_subgraphID] = getDefaultSubgraph();
398-
399-
// Update subgraph/curator balance
400-
subgraphCurator.totalShares = SHARES_PER_MINIMUM_STAKE;
441+
subgraph.curatorShares[_curator] = SHARES_PER_MINIMUM_STAKE;
401442

402443
// Update tokens used for stake
403444
tokens = tokens.sub(minimumCurationStake);
445+
446+
// Update global tokens balance
447+
totalTokens = totalTokens.add(minimumCurationStake);
404448
}
405449

406450
// Process unallocated tokens
@@ -409,27 +453,18 @@ contract Curation is Governed, BancorFormula {
409453
uint256 newShares = subgraphTokensToShares(_subgraphID, tokens);
410454

411455
// Update subgraph balances
412-
subgraph.totalTokens = subgraph.totalTokens.add(tokens);
413-
subgraph.totalShares = subgraph.totalShares.add(newShares);
414-
415-
// Update subgraph/curator balances
416-
subgraphCurator.totalShares = subgraphCurator.totalShares.add(
417-
newShares
418-
);
456+
increaseBalance(_curator, _subgraphID, tokens, newShares);
419457
}
420458

421-
// Update global tokens balance
422-
totalTokens = totalTokens.add(_amount);
423-
424459
emit CuratorStakeUpdated(
425460
_curator,
426461
_subgraphID,
427-
subgraphCurator.totalShares
462+
subgraph.curatorShares[_curator]
428463
);
429464
emit SubgraphStakeUpdated(
430465
_subgraphID,
431-
subgraph.totalShares,
432-
subgraph.totalTokens
466+
subgraph.shares,
467+
subgraph.tokens
433468
);
434469
}
435470
}

0 commit comments

Comments
 (0)