Skip to content

Commit e91537c

Browse files
committed
No longer rely entirely on constants for fork values. Manual methods exposed for requesting updates based on new information
1 parent 4f1fba2 commit e91537c

File tree

12 files changed

+157
-45
lines changed

12 files changed

+157
-45
lines changed

source/contracts/reporting/IReputationToken.sol

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@ contract IReputationToken is ITyped, ERC20 {
1515
function trustedUniverseTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
1616
function getUniverse() public view returns (IUniverse);
1717
function getTotalMigrated() public view returns (uint256);
18+
function getTotalTheoreticalSupply() public view returns (uint256);
1819
function mintForReportingParticipant(uint256 _amountMigrated) public returns (bool);
1920
}

source/contracts/reporting/IUniverse.sol

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ contract IUniverse is ITyped {
3434
function getOrCacheDesignatedReportStake() public returns (uint256);
3535
function getOrCacheDesignatedReportNoShowBond() public returns (uint256);
3636
function getOrCacheReportingFeeDivisor() public returns (uint256);
37+
function getDisputeThresholdForFork() public view returns (uint256);
38+
function getInitialReportMinValue() public view returns (uint256);
3739
function calculateFloatingValue(uint256 _badMarkets, uint256 _totalMarkets, uint256 _targetDivisor, uint256 _previousValue, uint256 _defaultValue, uint256 _floor) public pure returns (uint256 _newValue);
3840
function getOrCacheTargetReporterGasCosts() public returns (uint256);
3941
function getOrCacheMarketCreationCost() public returns (uint256);

source/contracts/reporting/Market.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ contract Market is DelegationTarget, Extractable, ITyped, Initializable, Ownable
154154
participants.push(_reportingParticipant);
155155
crowdsourcers = MapFactory(controller.lookup("MapFactory")).createMap(controller, this); // disavow other crowdsourcers
156156
controller.getAugur().logDisputeCrowdsourcerCompleted(universe, this, _reportingParticipant);
157-
if (IDisputeCrowdsourcer(msg.sender).getSize() >= Reporting.getDisputeThresholdForFork()) {
157+
if (IDisputeCrowdsourcer(msg.sender).getSize() >= universe.getDisputeThresholdForFork()) {
158158
universe.fork();
159159
} else {
160160
feeWindow = universe.getOrCreateNextFeeWindow();

source/contracts/reporting/Reporting.sol

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,7 @@ library Reporting {
88
uint256 private constant FORK_DURATION_SECONDS = 60 days;
99

1010
uint256 private constant INITIAL_REP_SUPPLY = 11 * 10 ** 6 * 10 ** 18; // 11 Million REP
11-
// CONSIDER: Should this be a constant?
12-
uint256 private constant DISPUTE_THRESHOLD_FOR_FORK = INITIAL_REP_SUPPLY / 80; // 1.25% of the REP total supply
13-
uint256 private constant INITIAL_REPORT_MIN_VALUE = 175 * 10**15; // This value will result in a maximum 20 round dispute sequence
14-
uint256 private constant DEFAULT_DESIGNATED_REPORT_STAKE = INITIAL_REPORT_MIN_VALUE;
15-
uint256 private constant DESIGNATED_REPORT_STAKE_FLOOR = INITIAL_REPORT_MIN_VALUE;
16-
uint256 private constant DEFAULT_DESIGNATED_REPORT_NO_SHOW_BOND = INITIAL_REPORT_MIN_VALUE;
17-
uint256 private constant DESIGNATED_REPORT_NO_SHOW_BOND_FLOOR = INITIAL_REPORT_MIN_VALUE;
11+
1812
uint256 private constant DEFAULT_VALIDITY_BOND = 1 ether / 100;
1913
uint256 private constant VALIDITY_BOND_FLOOR = 1 ether / 100;
2014
uint256 private constant DEFAULT_REPORTING_FEE_DIVISOR = 100; // 1% fees
@@ -31,7 +25,6 @@ library Reporting {
3125
uint256 private constant TARGET_REP_MARKET_CAP_MULTIPLIER = 5;
3226

3327
uint256 private constant FORK_MIGRATION_PERCENTAGE_BONUS_DIVISOR = 20; // 5% bonus to any REP migrated during a fork
34-
uint256 private constant FORK_REP_MIGRATION_VICTORY_DIVISOR = 2; // 50% of the REP supply in the forking universe has to migrate for a victory
3528

3629
function getDesignatedReportingDurationSeconds() internal pure returns (uint256) { return DESIGNATED_REPORTING_DURATION_SECONDS; }
3730
function getDisputeRoundDurationSeconds() internal pure returns (uint256) { return DISPUTE_ROUND_DURATION_SECONDS; }
@@ -40,22 +33,16 @@ library Reporting {
4033
function getGasToReport() internal pure returns (uint256) { return GAS_TO_REPORT; }
4134
function getDefaultReportingGasPrice() internal pure returns (uint256) { return DEFAULT_REPORTING_GAS_PRICE; }
4235
function getDefaultValidityBond() internal pure returns (uint256) { return DEFAULT_VALIDITY_BOND; }
43-
function getDefaultDesignatedReportStake() internal pure returns (uint256) { return DEFAULT_DESIGNATED_REPORT_STAKE; }
44-
function getDefaultDesignatedReportNoShowBond() internal pure returns (uint256) { return DEFAULT_DESIGNATED_REPORT_NO_SHOW_BOND; }
4536
function getValidityBondFloor() internal pure returns (uint256) { return VALIDITY_BOND_FLOOR; }
46-
function getDesignatedReportStakeFloor() internal pure returns (uint256) { return DESIGNATED_REPORT_STAKE_FLOOR; }
47-
function getDesignatedReportNoShowBondFloor() internal pure returns (uint256) { return DESIGNATED_REPORT_NO_SHOW_BOND_FLOOR; }
4837
function getTargetInvalidMarketsDivisor() internal pure returns (uint256) { return TARGET_INVALID_MARKETS_DIVISOR; }
4938
function getTargetIncorrectDesignatedReportMarketsDivisor() internal pure returns (uint256) { return TARGET_INCORRECT_DESIGNATED_REPORT_MARKETS_DIVISOR; }
5039
function getTargetDesignatedReportNoShowsDivisor() internal pure returns (uint256) { return TARGET_DESIGNATED_REPORT_NO_SHOWS_DIVISOR; }
5140
function getTargetRepMarketCapMultiplier() internal pure returns (uint256) { return TARGET_REP_MARKET_CAP_MULTIPLIER; }
5241
function getForkMigrationPercentageBonusDivisor() internal pure returns (uint256) { return FORK_MIGRATION_PERCENTAGE_BONUS_DIVISOR; }
53-
function getForkRepMigrationVictoryDivisor() internal pure returns (uint256) { return FORK_REP_MIGRATION_VICTORY_DIVISOR; }
5442
function getMaximumReportingFeeDivisor() internal pure returns (uint256) { return MAXIMUM_REPORTING_FEE_DIVISOR; }
5543
function getMinimumReportingFeeDivisor() internal pure returns (uint256) { return MINIMUM_REPORTING_FEE_DIVISOR; }
5644
function getDefaultReportingFeeDivisor() internal pure returns (uint256) { return DEFAULT_REPORTING_FEE_DIVISOR; }
5745
function getInitialREPSupply() internal pure returns (uint256) { return INITIAL_REP_SUPPLY; }
58-
function getDisputeThresholdForFork() internal pure returns (uint256) { return DISPUTE_THRESHOLD_FOR_FORK; }
5946

6047
function getCategoricalMarketNumTicks(uint8 _numOutcomes) internal pure returns (uint256) {
6148
require(_numOutcomes >= 2 && _numOutcomes <= 8);

source/contracts/reporting/ReputationToken.sol

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,15 @@ contract ReputationToken is DelegationTarget, Extractable, ITyped, Initializable
2323
uint256 constant public decimals = 18;
2424
IUniverse private universe;
2525
uint256 private totalMigrated;
26+
mapping(address => uint256) migratedToSibling;
27+
uint256 private parentTotalTheoreticalSupply;
28+
uint256 private totalTheoreticalSupply;
2629

2730
function initialize(IUniverse _universe) public onlyInGoodTimes beforeInitialized returns (bool) {
2831
endInitialization();
2932
require(_universe != address(0));
3033
universe = _universe;
34+
updateParentTotalTheoreticalSupply();
3135
return true;
3236
}
3337

@@ -46,7 +50,9 @@ contract ReputationToken is DelegationTarget, Extractable, ITyped, Initializable
4650
totalMigrated += _attotokens;
4751
// Award a bonus if migration is done before the fork has resolved and update the universe tentative winner tracking
4852
if (!_parentUniverse.getForkingMarket().isFinalized()) {
49-
mint(_reporter, _attotokens.div(Reporting.getForkMigrationPercentageBonusDivisor()));
53+
uint256 _bonus = _attotokens.div(Reporting.getForkMigrationPercentageBonusDivisor());
54+
mint(_reporter, _bonus);
55+
totalTheoreticalSupply += _bonus;
5056
_parentUniverse.updateTentativeWinningChildUniverse(universe.getParentPayoutDistributionHash());
5157
}
5258
return true;
@@ -64,7 +70,9 @@ contract ReputationToken is DelegationTarget, Extractable, ITyped, Initializable
6470
IUniverse _parentUniverse = universe.getParentUniverse();
6571
IReportingParticipant _reportingParticipant = IReportingParticipant(msg.sender);
6672
require(_parentUniverse.isContainerForReportingParticipant(_reportingParticipant));
67-
mint(_reportingParticipant, _amountMigrated / 2);
73+
uint256 _bonus = _amountMigrated / 2;
74+
mint(_reportingParticipant, _bonus);
75+
totalTheoreticalSupply += _bonus;
6876
return true;
6977
}
7078

@@ -112,6 +120,32 @@ contract ReputationToken is DelegationTarget, Extractable, ITyped, Initializable
112120
return totalMigrated;
113121
}
114122

123+
function updateSiblingMigrationTotal(IReputationToken _token) public returns (bool) {
124+
require(_token != this);
125+
IUniverse _supposedUniverse = _token.getUniverse();
126+
require(_token == universe.getParentUniverse().getChildUniverse(_supposedUniverse.getParentPayoutDistributionHash()).getReputationToken());
127+
totalTheoreticalSupply += migratedToSibling[_token];
128+
migratedToSibling[_token] = _token.getTotalMigrated();
129+
totalTheoreticalSupply -= migratedToSibling[_token];
130+
return true;
131+
}
132+
133+
function updateParentTotalTheoreticalSupply() public returns (bool) {
134+
IUniverse _parentUniverse = universe.getParentUniverse();
135+
totalTheoreticalSupply -= parentTotalTheoreticalSupply;
136+
if (_parentUniverse == IUniverse(0)) {
137+
parentTotalTheoreticalSupply = Reporting.getInitialREPSupply();
138+
} else {
139+
parentTotalTheoreticalSupply = _parentUniverse.getReputationToken().getTotalTheoreticalSupply();
140+
}
141+
totalTheoreticalSupply += parentTotalTheoreticalSupply;
142+
return true;
143+
}
144+
145+
function getTotalTheoreticalSupply() public view returns (uint256) {
146+
return totalTheoreticalSupply;
147+
}
148+
115149
function onTokenTransfer(address _from, address _to, uint256 _value) internal returns (bool) {
116150
controller.getAugur().logReputationTokensTransferred(universe, _from, _to, _value);
117151
return true;

source/contracts/reporting/Universe.sol

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ contract Universe is DelegationTarget, Extractable, ITyped, Initializable, IUniv
2929
bytes32 private tentativeWinningChildUniversePayoutDistributionHash;
3030
uint256 private forkEndTime;
3131
uint256 private forkReputationGoal;
32+
uint256 private disputeThresholdForFork;
33+
uint256 private initialReportMinValue;
3234
mapping(uint256 => IFeeWindow) private feeWindows;
3335
mapping(address => bool) private markets;
3436
mapping(bytes32 => IUniverse) private childUniverses;
@@ -45,6 +47,7 @@ contract Universe is DelegationTarget, Extractable, ITyped, Initializable, IUniv
4547
parentUniverse = _parentUniverse;
4648
parentPayoutDistributionHash = _parentPayoutDistributionHash;
4749
reputationToken = ReputationTokenFactory(controller.lookup("ReputationTokenFactory")).createReputationToken(controller, this);
50+
updateForkValues();
4851
require(reputationToken != address(0));
4952
return true;
5053
}
@@ -54,18 +57,18 @@ contract Universe is DelegationTarget, Extractable, ITyped, Initializable, IUniv
5457
require(isContainerForMarket(IMarket(msg.sender)));
5558
forkingMarket = IMarket(msg.sender);
5659
forkEndTime = controller.getTimestamp() + Reporting.getForkDurationSeconds();
57-
// We pre calculate the amount of REP needed to determine a winner early in a fork. We assume maximum possible fork inflation in every fork so this is hard to achieve with every subsequent fork and may become impossible in some universes.
58-
if (parentUniverse != IUniverse(0)) {
59-
uint256 _previousForkReputationGoal = parentUniverse.getForkReputationGoal();
60-
forkReputationGoal = _previousForkReputationGoal + (_previousForkReputationGoal / Reporting.getForkMigrationPercentageBonusDivisor());
61-
} else {
62-
// We're using a hardcoded supply value instead of getting the total REP supply from the token since at launch we will start out with a 0 supply token and users will migrate legacy REP to this token. Since the first fork may occur before all REP migrates we want to count that unmigrated REP too since it may participate in the fork eventually.
63-
forkReputationGoal = Reporting.getInitialREPSupply() / Reporting.getForkRepMigrationVictoryDivisor();
64-
}
6560
controller.getAugur().logUniverseForked();
6661
return true;
6762
}
6863

64+
function updateForkValues() public returns (bool) {
65+
uint256 _totalRepSupply = reputationToken.getTotalTheoreticalSupply();
66+
forkReputationGoal = _totalRepSupply.div(2); // 50% of REP migrating results in a victory in a fork
67+
disputeThresholdForFork = _totalRepSupply.div(80); // 1.25% of the total rep supply
68+
initialReportMinValue = disputeThresholdForFork.div(3).div(2**18) + 1; // This value will result in a maximum 20 round dispute sequence
69+
return true;
70+
}
71+
6972
function getTypeName() public view returns (bytes32) {
7073
return "Universe";
7174
}
@@ -94,6 +97,14 @@ contract Universe is DelegationTarget, Extractable, ITyped, Initializable, IUniv
9497
return forkReputationGoal;
9598
}
9699

100+
function getDisputeThresholdForFork() public view returns (uint256) {
101+
return disputeThresholdForFork;
102+
}
103+
104+
function getInitialReportMinValue() public view returns (uint256) {
105+
return initialReportMinValue;
106+
}
107+
97108
function getFeeWindow(uint256 _feeWindowId) public view returns (IFeeWindow) {
98109
return feeWindows[_feeWindowId];
99110
}
@@ -319,7 +330,7 @@ contract Universe is DelegationTarget, Extractable, ITyped, Initializable, IUniv
319330
uint256 _incorrectDesignatedReportMarketsInPreviousWindow = _previousFeeWindow.getNumIncorrectDesignatedReportMarkets();
320331
uint256 _previousDesignatedReportStakeInAttoRep = designatedReportStakeInAttoRep[_previousFeeWindow];
321332

322-
_currentDesignatedReportStakeInAttoRep = calculateFloatingValue(_incorrectDesignatedReportMarketsInPreviousWindow, _totalMarketsInPreviousWindow, Reporting.getTargetIncorrectDesignatedReportMarketsDivisor(), _previousDesignatedReportStakeInAttoRep, Reporting.getDefaultDesignatedReportStake(), Reporting.getDesignatedReportStakeFloor());
333+
_currentDesignatedReportStakeInAttoRep = calculateFloatingValue(_incorrectDesignatedReportMarketsInPreviousWindow, _totalMarketsInPreviousWindow, Reporting.getTargetIncorrectDesignatedReportMarketsDivisor(), _previousDesignatedReportStakeInAttoRep, initialReportMinValue, initialReportMinValue);
323334
designatedReportStakeInAttoRep[_feeWindow] = _currentDesignatedReportStakeInAttoRep;
324335
return _currentDesignatedReportStakeInAttoRep;
325336
}
@@ -335,7 +346,7 @@ contract Universe is DelegationTarget, Extractable, ITyped, Initializable, IUniv
335346
uint256 _designatedReportNoShowsInPreviousWindow = _previousFeeWindow.getNumDesignatedReportNoShows();
336347
uint256 _previousDesignatedReportNoShowBondInAttoRep = designatedReportNoShowBondInAttoRep[_previousFeeWindow];
337348

338-
_currentDesignatedReportNoShowBondInAttoRep = calculateFloatingValue(_designatedReportNoShowsInPreviousWindow, _totalMarketsInPreviousWindow, Reporting.getTargetDesignatedReportNoShowsDivisor(), _previousDesignatedReportNoShowBondInAttoRep, Reporting.getDefaultDesignatedReportNoShowBond(), Reporting.getDesignatedReportNoShowBondFloor());
349+
_currentDesignatedReportNoShowBondInAttoRep = calculateFloatingValue(_designatedReportNoShowsInPreviousWindow, _totalMarketsInPreviousWindow, Reporting.getTargetDesignatedReportNoShowsDivisor(), _previousDesignatedReportNoShowBondInAttoRep, initialReportMinValue, initialReportMinValue);
339350
designatedReportNoShowBondInAttoRep[_feeWindow] = _currentDesignatedReportNoShowBondInAttoRep;
340351
return _currentDesignatedReportNoShowBondInAttoRep;
341352
}

tests/conftest.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ def createScalarMarket(self, universe, endTime, feePerEthInWei, denominationToke
377377
def createReasonableBinaryMarket(self, universe, denominationToken, sender=tester.k0, topic="", description="description", extraInfo=""):
378378
return self.createBinaryMarket(
379379
universe = universe,
380-
endTime = long(self.chain.head_state.timestamp + timedelta(days=1).total_seconds()),
380+
endTime = long(self.contracts["Time"].getTimestamp() + timedelta(days=1).total_seconds()),
381381
feePerEthInWei = 10**16,
382382
denominationToken = denominationToken,
383383
designatedReporterAddress = tester.a0,
@@ -390,7 +390,7 @@ def createReasonableCategoricalMarket(self, universe, numOutcomes, denominationT
390390
return self.createCategoricalMarket(
391391
universe = universe,
392392
numOutcomes = numOutcomes,
393-
endTime = long(self.chain.head_state.timestamp + timedelta(days=1).total_seconds()),
393+
endTime = long(self.contracts["Time"].getTimestamp() + timedelta(days=1).total_seconds()),
394394
feePerEthInWei = 10**16,
395395
denominationToken = denominationToken,
396396
designatedReporterAddress = tester.a0,
@@ -399,7 +399,7 @@ def createReasonableCategoricalMarket(self, universe, numOutcomes, denominationT
399399
def createReasonableScalarMarket(self, universe, maxPrice, minPrice, numTicks, denominationToken, sender=tester.k0):
400400
return self.createScalarMarket(
401401
universe = universe,
402-
endTime = long(self.chain.head_state.timestamp + timedelta(days=1).total_seconds()),
402+
endTime = long(self.contracts["Time"].getTimestamp() + timedelta(days=1).total_seconds()),
403403
feePerEthInWei = 10**16,
404404
denominationToken = denominationToken,
405405
maxPrice= maxPrice,

0 commit comments

Comments
 (0)