Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Abstract Registry Challenge #76

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion conf/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,3 @@
]
}
}

8 changes: 8 additions & 0 deletions contracts/Challenge/ChallengeFactoryInterface.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
pragma solidity ^0.4.8;

import "../Registry.sol";
import "./ChallengeInterface.sol";

contract ChallengeFactoryInterface {
function createChallenge(address _challenger, address _listingOwner, Registry _registry) external returns (ChallengeInterface);
}
19 changes: 19 additions & 0 deletions contracts/Challenge/ChallengeInterface.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
pragma solidity ^0.4.8;

contract ChallengeInterface {
/// @dev returns whether challenge is ready for resolution
function ended() public view returns (bool);

/// @dev returns whether challenge has passed
function passed() public view returns (bool);

/// @dev returns how much token the challenger staked
function stake() public view returns (uint);

/// @dev returns the amount of challenge deposit tokens
/// the challenge requires to carry out functionality
function requiredTokenDeposit() public view returns(uint);

/// @dev returns the number of tokens awarded to the winning party
function tokenRewardAmount() public view returns (uint);
}
192 changes: 192 additions & 0 deletions contracts/Challenge/PLCRVotingChallenge.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
pragma solidity ^0.4.8;
import "../Parameterizer.sol";
import "../Registry.sol";
import "dll/DLL.sol";
import "attrstore/AttributeStore.sol";
import "zeppelin/math/SafeMath.sol";
import "plcr-revival/PLCRVoting.sol";
import "./ChallengeInterface.sol";
/**
@title Partial-Lock-Commit-Reveal Voting scheme with ERC20 tokens
@author Team: Aspyn Palatnick, Cem Ozer, Yorke Rhodes
*/
contract PLCRVotingChallenge is ChallengeInterface {

// ============
// EVENTS:
// ============

event _VoteCommitted(bytes32 UUID, address voterAddress, uint numTokens);
event _VoteRevealed(address voterAddress, uint numTokens, uint votesFor, uint votesAgainst);
event _PollCreated(uint voteQuorum, uint commitEndDate, uint revealEndDate, uint pollID);
event _VotingRightsGranted(uint numTokens);
event _VotingRightsWithdrawn(uint numTokens);
event _RewardClaimed(uint reward, address indexed voter);

// ============
// DATA STRUCTURES:
// ============

using AttributeStore for AttributeStore.Data;
using DLL for DLL.Data;
using SafeMath for uint;

// ============
// GLOBAL VARIABLES:
// ============

address public challenger; /// the address of the challenger
address public listingOwner; /// the address of the listingOwner
Registry public registry;
PLCRVoting public voting; /// address of PLCRVoting Contract
uint public pollID; /// pollID of PLCRVoting
uint public commitEndDate; /// expiration date of commit period for poll
uint public revealEndDate; /// expiration date of reveal period for poll
uint public voteQuorum; /// number of votes required for a proposal to pass
uint public rewardPool; /// pool of tokens to be distributed to winning voters
uint public challengerStake; /// number of tokens at stake for either party during challenge
uint public votesFor; /// tally of votes supporting proposal
uint public votesAgainst; /// tally of votes countering proposal

uint public voterTokensClaimed;
uint public voterRewardsClaimed;

uint public commitStageLen;
uint public revealStageLen;

mapping(address => bool) public didCommit; /// indicates whether an address committed a vote for this poll
mapping(address => bool) public didReveal; /// indicates whether an address revealed a vote for this poll

mapping(address => uint) public voteTokenBalance; // maps user's address to voteToken balance
mapping(address => bool) public tokenClaims; // Indicates whether a voter has claimed a reward yet

AttributeStore.Data store;

// ============
// MODIFIERS:
// ============

modifier onlyChallenger() {
require(msg.sender == challenger);
_;
}

// ============
// CONSTRUCTOR:
// ============

/**
@dev Initializes voteQuorum, commitDuration, revealDuration, and pollNonce in addition to token contract and trusted mapping
*/
function PLCRVotingChallenge(address _challenger, address _listingOwner, Registry _registry, Parameterizer _parameterizer) public {
challenger = _challenger;
listingOwner = _listingOwner;
registry = _registry;
voting = _parameterizer.voting();

commitStageLen = _parameterizer.get("commitStageLen");
revealStageLen = _parameterizer.get("revealStageLen");
voteQuorum = _parameterizer.get("voteQuorum");
challengerStake = _parameterizer.get("minDeposit");
pollID = voting.startPoll( voteQuorum, commitStageLen, revealStageLen);

uint oneHundred = 100; // Kludge that we need to use SafeMath
rewardPool = ((oneHundred.sub(_parameterizer.get("dispensationPct"))).mul(challengerStake)).div(100);
}

// =================
// VOTING INTERFACE:
// =================

/**
@dev Called by a voter to claim their reward for each completed vote
*/
function claimVoterReward() public {
// Ensures the voter has not already claimed tokens
require(tokenClaims[msg.sender] == false);
require(ended());

uint voterTokens = voting.getNumPassingTokens(msg.sender, pollID);
uint reward = voterReward(msg.sender);

voterTokensClaimed += voterTokens;
voterRewardsClaimed += reward;

// Ensures a voter cannot claim tokens again
tokenClaims[msg.sender] = true;

require(registry.token().transferFrom(registry, this, reward));
require(registry.token().transfer(msg.sender, reward));

_RewardClaimed(reward, msg.sender);
}

/**
@dev Calculates the provided voter's token reward.
@param _voter The address of the voter whose reward balance is to be returned
@return The uint indicating the voter's reward
*/
function voterReward(address _voter)
public view returns (uint) {
uint voterTokens = voting.getNumPassingTokens(_voter, pollID);
uint remainingRewardPool = rewardPool - voterRewardsClaimed;
uint remainingTotalTokens = voting.getTotalNumberOfTokensForWinningOption(pollID) - voterTokensClaimed;
return (voterTokens * remainingRewardPool) / remainingTotalTokens;
}

/**
@dev Determines the number of tokens awarded to the winning party
*/
function tokenRewardAmount() public view returns (uint) {
require(ended());

// Edge case, nobody voted, give all tokens to the challenger.
if (voting.getTotalNumberOfTokensForWinningOption(pollID) == 0) {
return challengerStake * 2;
}

return challengerStake * 2 - rewardPool;
}

// ====================
// CHALLENGE INTERFACE:
// ====================

/**
@notice Returns amount of tokens staked by challenger
@dev Returns amount of tokens staked by challenger
@return integer representing stake
*/
function stake() view public returns (uint) {
return challengerStake;
}

/**
@notice Returns tokens required by challenge contract
@dev Returns tokens required by challenge contract
@return Returns tokens required by challenge contract
*/
function requiredTokenDeposit() public view returns(uint) {
return rewardPool;
}

/**
@notice Checks if a challenge is ended
@dev Checks pollEnded for the pollID
@return Boolean indication if challenge is ended
*/
function ended() view public returns (bool) {
return voting.pollEnded(pollID);
}

/**
@notice Determines if the challenge has passed
@dev Check if votesAgainst out of totalVotes exceeds votesQuorum (requires ended)
*/
function passed() public view returns (bool) {
require(ended());

// if votes do not vote in favor of listing, challenge passes
return !voting.isPassed(pollID);
}
}
41 changes: 41 additions & 0 deletions contracts/Challenge/PLCRVotingChallengeFactory.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
pragma solidity ^0.4.8;

import "../Parameterizer.sol";
import "../Registry.sol";
import "./ChallengeFactoryInterface.sol";
import "./PLCRVotingChallenge.sol";

contract PLCRVotingChallengeFactory is ChallengeFactoryInterface {

// ============
// STATE:
// ============
// GLOBAL VARIABLES
Parameterizer public parameterizer; // Address of the TCR's associeted Parameterizer contract

// ------------
// CONSTRUCTOR:
// ------------
/// @dev Constructor Sets the global state for the factory
/// @param _parameterizer Address of the TCR's associeted Parameterizer contract
function PLCRVotingChallengeFactory(address _parameterizer) public {
parameterizer = Parameterizer(_parameterizer);
}

// --------------------
// FACTORY INTERFACE:
// --------------------
/// @dev createChallenge Creates challenge associated to a Registry listing
/// @param _challenger Address of the challenger
/// @param _listingOwner Address of the listing owner
/// @return ChallengeInterface Newly created Challenge
function createChallenge(address _challenger, address _listingOwner, Registry _registry) external returns (ChallengeInterface) {
return new PLCRVotingChallenge(
_challenger,
_listingOwner,
_registry,
parameterizer
);
}

}
16 changes: 16 additions & 0 deletions contracts/PLCRVotingRegistry.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
pragma solidity ^0.4.11;

import "./Parameterizer.sol";
import "./Challenge/PLCRVotingChallengeFactory.sol";

contract PLCRVotingRegistry is Registry {

/**
@dev Initializer. Create a new PLCRVotingChallengeFactory, then init the registry
*/
function init(address _token, address _parameterizer, string _name) public {
challengeFactory = new PLCRVotingChallengeFactory(_parameterizer);
super.init(_token, _parameterizer, _name);
}

}
14 changes: 14 additions & 0 deletions contracts/PLCRVotingRegistryFactory.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
pragma solidity ^0.4.20;

import "./RegistryFactory.sol";
import "./ParameterizerFactory.sol";
import "./PLCRVotingRegistry.sol";

contract PLCRVotingRegistryFactory is RegistryFactory {

/// @dev constructor deploys a new proxyFactory.
constructor(ParameterizerFactory _parameterizerFactory) RegistryFactory(_parameterizerFactory) public {
canonizedRegistry = new PLCRVotingRegistry();
}

}
1 change: 0 additions & 1 deletion contracts/Parameterizer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -397,4 +397,3 @@ contract Parameterizer {
params[keccak256(abi.encodePacked(_name))] = _value;
}
}

Loading