Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- pragma solidity ^ 0.6.4;
- pragma experimental ABIEncoderV2;
- contract Oracle{
- address payable ORACLE = address(0);
- address address0 = address(0);
- struct Poll{
- uint8 dataType; // string, uint, bool, address
- //commit
- mapping(address => bool) committed;
- mapping(address => bytes) commitHash;
- //reveal
- mapping(address => bool) revealed;
- mapping(address => bool) rejected;
- mapping(address => bool) voted;
- mapping(address => string) stringVotes;
- mapping(address => uint) uintVotes;
- mapping(address => bool) boolVotes;
- mapping(address => address) addressVotes;
- }
- struct RequestTicket{
- uint ID;
- address sender;
- string query;
- uint timeRequested;
- bool finalized;
- Poll poll;
- uint txCoverageFee;
- uint serviceFee;
- bool needsResponse;
- bool rejected;
- string resolvedString;
- uint resolvedUint;
- bool resolvedBool;
- address resolvedAddress;
- mapping(address => bool) punished;
- }
- //oracle configs
- uint constant ROUNDTABLE_SEATS = 0;
- uint constant COMMIT_TIME_WINDOW = 1;
- uint constant REVEAL_TIME_WINDOW = 2;
- uint constant DELEGATE_REWARDSHARE = 3;
- uint constant ELECTORATE_REWARDSHARE = 4;
- uint constant FREEZE_TIMEOUT = 5;
- uint constant TX_FEE_PER = 6;
- uint constant SERVICE_FEE = 7;
- uint constant CONFIGS = 8;
- uint[] oracleConfigurations = new uint[](CONFIGS);
- mapping(uint/*configID*/ => mapping(uint => uint) ) public totalVotes_forEach_configOption;
- mapping(uint/*configID*/ => mapping(address => uint) ) public individualsSelectedOption;
- mapping(address => uint) resolveWeight;
- mapping(address => uint) weightLocked;
- RequestTicket[] requestTickets;
- //ROUND TABLE & Candidates
- mapping(uint => address) public chairsCandidate; // only looks at the first X indexes
- mapping(address => uint) candidatesChair;
- mapping(address => uint) timeSeated; // watchers aren't responsible for requestTickets that came in before them
- mapping(address => bool) frozen;
- mapping(address => uint) timeWhenThawedOut;
- mapping(address => bool) paused; // self pause
- mapping(address => bool) hasChair;
- uint chairs;
- uint public hotSeats;
- uint256 constant scaleFactor = 0x10000000000000000;
- //PAYROLL
- mapping(address => uint) earnings;
- mapping(address => uint) totalShares;
- mapping(address => mapping(address => uint256)) public shares;
- mapping(address => mapping(address => uint256)) payouts;
- mapping(address => uint) earningsPerShare;
- //Tx Coverage fee
- uint earningsPerWatcher;
- uint totalWatchers;
- mapping(address => uint256) watcherPayouts;
- //lazy UI data
- mapping(address => address[]) public yourBacking;
- mapping(address => mapping(address => bool)) public alreadyBacking;
- ResolveToken resolveToken;
- constructor(address _resolve) public{
- resolveToken = ResolveToken(_resolve);
- }
- function addressPayable(address addr) public pure returns(address payable){
- return address(uint160(addr));
- }
- function addShares(address pool, address account, uint amount) internal{
- update(pool, addressPayable(account));
- totalShares[pool] += amount;
- shares[pool][account] += amount;
- if(pool == ORACLE){
- updateWatcherTxEarnings(addressPayable(account));
- totalWatchers += 1;
- }
- }
- function removeShares(address pool, address account, uint amount) internal{
- update(pool, addressPayable(account));
- totalShares[pool] -= amount;
- shares[pool][account] -= amount;
- if(pool == ORACLE){
- updateWatcherTxEarnings(addressPayable(account));
- totalWatchers -= 1;
- }
- }
- event Cashout(address account, uint amount);
- event WatcherPayroll(address watcher, uint paidOut);
- function update(address pool, address payable account) internal {
- uint owedPerShare = earningsPerShare[pool] - payouts[pool][account];
- uint newMoney = shares[pool][account] * owedPerShare;
- payouts[pool][account] = earningsPerShare[pool];
- if(pool == ORACLE){
- uint drs = oracleConfigurations[DELEGATE_REWARDSHARE];
- uint ers = oracleConfigurations[ELECTORATE_REWARDSHARE];
- uint eth4Watcher = newMoney *drs/(drs+ers);
- earnings[account] += eth4Watcher/scaleFactor;
- earningsPerShare[account] += (newMoney - eth4Watcher)/totalShares[account];
- emit Cashout(account, eth4Watcher/scaleFactor);
- emit WatcherPayroll(account, (newMoney - eth4Watcher)/totalShares[account]);
- }else{
- earnings[account] += newMoney/scaleFactor;
- emit Cashout(account, newMoney/scaleFactor);
- }
- }
- event TxCashout(address watcher, uint amount);
- function updateWatcherTxEarnings(address payable watcher) internal {
- uint owed = earningsPerWatcher - watcherPayouts[watcher];
- watcherPayouts[watcher] = earningsPerWatcher;
- earnings[watcher] += owed;
- emit TxCashout(watcher, owed);
- }
- event StakeResolves( address indexed addr, uint256 amountStaked, bytes _data );
- function tokenFallback(address from, uint value, bytes calldata _data) external{
- if(msg.sender == address(resolveToken) ){
- resolveWeight[from] += value;
- //update option totals
- uint option;
- for(uint8 config = 0;config<CONFIGS;config+=1){
- option = individualsSelectedOption[config][from];
- totalVotes_forEach_configOption[config][option] += value;
- assertOption(config, option);
- }
- emit StakeResolves(from, value, _data);
- }else{
- revert();
- }
- }
- event UnstakeResolves(address sender, uint amount);
- function unstakeResolves(uint amount) public{
- address sender = msg.sender;
- if( amount <= ( resolveWeight[sender] - weightLocked[sender] ) ){
- resolveWeight[sender] -= amount;
- for(uint config = 0; config<CONFIGS; config+=1){
- totalVotes_forEach_configOption[config][individualsSelectedOption[config][sender]] -= amount;
- }
- emit UnstakeResolves(sender, amount);
- resolveToken.transfer(sender, amount);
- }else{
- revert();
- }
- }
- event BackCandidate(address sender,address candidate, uint amount);
- function backCandidate(address candidate, uint amount, bool _assert) public{
- address sender = msg.sender;
- require(candidate!=ORACLE);
- if( amount <= ( resolveWeight[sender] - weightLocked[sender] ) && !isWatcher(candidate) ){
- weightLocked[sender] += amount;
- addShares(candidate, sender, amount);
- //I guess candidates should be able to opt into pausing themselves instead of being cast as a delegate right away.
- //Idk where else to write this comment
- //If the candidate isn't seated, and freezing and pause isn't preventing them from being seated ... then assertCandidate()
- if( candidatesChair[candidate] >= hotSeats && !frausted(candidate) && _assert){
- assertCandidate(candidate);
- }
- emit BackCandidate(sender, candidate, amount);
- //LAZY U.I.
- if(!alreadyBacking[sender][candidate]){
- yourBacking[sender].push(candidate);
- alreadyBacking[sender][candidate] = true;
- }
- }else{
- revert();
- }
- }
- event WithdrawBacking(address sender,address candidate, uint amount);
- function withdrawBacking(address candidate, uint amount) public{
- address sender = msg.sender;
- if( amount <= shares[candidate][sender] && !frozen[candidate] && ( !(candidatesChair[candidate]<hotSeats) || paused[candidate] ) ){
- weightLocked[sender] -= amount;
- removeShares(candidate, sender, amount);
- emit WithdrawBacking(sender, candidate, amount);
- }else{
- revert();
- }
- }
- function frausted(address candidate) public view returns(bool){
- return paused[candidate] || frozen[candidate];
- }
- event AssertCandidate(address candidate, bool asserted, address replacedWatcher, uint newSeat);
- function assertCandidate(address candidate) public returns(bool){
- if(candidatesChair[candidate] >= hotSeats && candidate != ORACLE && !frausted(candidate) ){
- address weakestLink = chairsCandidate[0];
- bool thereIsAFraustedDelegate;
- uint chairNumber;
- address comparedDelegate;
- for(uint i = 0; i<hotSeats; i+=1){
- comparedDelegate = chairsCandidate[i];
- if(thereIsAFraustedDelegate && frausted(comparedDelegate) ){
- if( totalShares[comparedDelegate] < totalShares[weakestLink] ){
- weakestLink = comparedDelegate;
- chairNumber = i;
- }
- }else{
- if( frausted(comparedDelegate) ){
- thereIsAFraustedDelegate = true;
- weakestLink = comparedDelegate;
- chairNumber = i;
- }else if( totalShares[comparedDelegate] < totalShares[weakestLink] ){
- weakestLink = comparedDelegate;
- chairNumber = i;
- }
- }
- }
- //check if we can swap out seated watcher & then swap 'em
- if( totalShares[candidate] > totalShares[weakestLink] || thereIsAFraustedDelegate ){
- uint theChairForTheLoser;
- if(hasChair[candidate]){
- theChairForTheLoser = candidatesChair[candidate];
- }else{
- hasChair[candidate] = true;
- theChairForTheLoser = chairs;
- chairs += 1;
- }
- //###
- //old candidate getting bumped
- removeShares(ORACLE, weakestLink, totalShares[weakestLink]);
- candidatesChair[ weakestLink ] = theChairForTheLoser;
- chairsCandidate[theChairForTheLoser] = weakestLink;
- //new candidate sitting at the round table
- addShares(ORACLE, candidate, totalShares[candidate]);
- chairsCandidate[chairNumber] = candidate;
- candidatesChair[candidate] = chairNumber;
- emit AssertCandidate(candidate, true, weakestLink, chairNumber);
- return true;
- }else{
- if(!hasChair[candidate]){
- hasChair[candidate] = true;
- candidatesChair[candidate] = chairs;
- chairsCandidate[chairs] = candidate;
- emit AssertCandidate(candidate, false, address0, chairs);
- chairs+=1;
- return false;
- }else{
- revert();
- }
- }
- }else{
- revert();
- }
- }
- event OptionVote(address sender, uint8 config, uint option, uint weight);
- function optionVote(bool[] memory isModifying, uint[] memory modifiedOptions) public{
- address sender = msg.sender;
- for(uint8 config = 0; config<CONFIGS; config+=1){
- if(isModifying[config]){
- uint selectedOption = individualsSelectedOption[config][sender];
- totalVotes_forEach_configOption[config][ selectedOption ] -= resolveWeight[sender];
- individualsSelectedOption[config][sender] = modifiedOptions[config];
- totalVotes_forEach_configOption[config][ modifiedOptions[config] ] += resolveWeight[sender];
- emit OptionVote(sender, config, modifiedOptions[config], resolveWeight[sender]);
- assertOption( config, modifiedOptions[config] );
- }
- }
- }
- event AssertOption(uint8 config, uint option);
- function assertOption(uint8 config, uint option) public{
- if( totalVotes_forEach_configOption[config][option] > totalVotes_forEach_configOption[config][ oracleConfigurations[config] ] ){
- oracleConfigurations[config] = option;
- emit AssertOption(config, option);
- }
- }
- function isWatcher(address candidate) public view returns(bool){
- return candidatesChair[candidate]<hotSeats && !frausted(candidate);
- }
- function getFee() public view returns(uint txCoverageFee, uint serviceFee){
- uint activeWatchers;
- for(uint chair = 0; chair<hotSeats; chair+=1){
- if( !frausted(chairsCandidate[chair]) ){
- activeWatchers += 1;
- }
- }
- return ( TX_FEE_PER*activeWatchers, oracleConfigurations[SERVICE_FEE] );
- }
- //------------------------------ Request Ticket Life Cycle
- event FileRequestTicket(address sender, uint ticketID, string query, uint timeRequested, uint8 dataType, uint feePaid);
- function fileRequestTicket(string memory query, uint8 returnType, bool needsResponse) public payable returns(uint ticketID){
- uint ETH = msg.value;
- (uint txCoverageFee, uint serviceFee) = getFee();
- if(ETH == txCoverageFee + serviceFee ){
- RequestTicket memory ticket;
- ticket.query = query;
- ticket.timeRequested = now;
- ticket.ID = requestTickets.length;
- ticket.sender = msg.sender;
- ticket.needsResponse = needsResponse;
- Poll memory poll;
- if(returnType>3)
- returnType = 3;
- poll.dataType = returnType;
- ticket.poll = poll;
- requestTickets.push(ticket);
- ticket.txCoverageFee = txCoverageFee;
- ticket.serviceFee = serviceFee;
- emit FileRequestTicket(msg.sender, ticketID, query, now, returnType, ETH);
- return ticket.ID;
- }else{
- revert();
- }
- }
- event CommitVote(address sender, bytes hash);
- function commitVote(uint[] memory tickets, bytes[] memory voteHashes) public{
- address sender = msg.sender;
- //RequestTicket storage ticket;
- for(uint R; R<tickets.length; R+=1 ){
- //ticket = requestTickets[ tickets[R] ];
- if(now <= requestTickets[ tickets[R] ].timeRequested + oracleConfigurations[COMMIT_TIME_WINDOW] ){
- requestTickets[ tickets[R] ].poll.committed[sender] = true;
- requestTickets[ tickets[R] ].poll.commitHash[sender] = voteHashes[R];
- emit CommitVote(sender, voteHashes[R]);
- }
- }
- }
- event RevealVote(address voter, uint ticketID, bool rejected, /*suba*/ string stringVote, uint uintVote, bool boolVote, address addressVote);
- function revealVote(uint[] memory tickets, bool[] memory rejected, string[] memory stringVotes, uint[] memory uintVotes, bool[] memory boolVotes, address[] memory addressVotes, string[] memory passwords) public{
- address sender = msg.sender;
- RequestTicket memory ticket;
- bytes memory abiEncodePacked;
- for(uint R; R<tickets.length; R+=1 ){
- ticket = requestTickets[ tickets[R] ];
- if(now > ticket.timeRequested + oracleConfigurations[COMMIT_TIME_WINDOW] && now <= ticket.timeRequested + oracleConfigurations[COMMIT_TIME_WINDOW] + oracleConfigurations[REVEAL_TIME_WINDOW] ){
- if(ticket.poll.dataType == 0){
- abiEncodePacked = abi.encodePacked( rejected[R], stringVotes[R], passwords[R] );
- }else if(ticket.poll.dataType == 1){
- abiEncodePacked = abi.encodePacked( rejected[R], uintVotes[R], passwords[R] );
- }else if(ticket.poll.dataType == 2){
- abiEncodePacked = abi.encodePacked( rejected[R], boolVotes[R], passwords[R] );
- }else if(ticket.poll.dataType == 3){
- abiEncodePacked = abi.encodePacked( rejected[R], addressVotes[R], passwords[R] );
- }
- if( compareBytes( abiEncodePacked, requestTickets[ tickets[R] ].poll.commitHash[sender]) ){
- requestTickets[ tickets[R] ].poll.revealed[sender] = true;
- if(rejected[R]){
- requestTickets[ tickets[R] ].poll.rejected[sender] = true;
- }else{
- requestTickets[ tickets[R] ].poll.voted[sender] = true;
- if(ticket.poll.dataType == 0){
- requestTickets[ tickets[R] ].poll.stringVotes[sender] = stringVotes[R];
- }else if(ticket.poll.dataType == 1){
- requestTickets[ tickets[R] ].poll.uintVotes[sender] = uintVotes[R];
- }else if(ticket.poll.dataType == 2){
- requestTickets[ tickets[R] ].poll.boolVotes[sender] = boolVotes[R];
- }else if(ticket.poll.dataType == 3){
- requestTickets[ tickets[R] ].poll.addressVotes[sender] = addressVotes[R];
- }
- }
- emit RevealVote(sender, tickets[R], rejected[R], stringVotes[R], uintVotes[R], boolVotes[R], addressVotes[R]);
- }
- }
- }
- }
- event FinalizedRequestOptions(string[] stringOptions, uint[] uintOptions, bool[] boolOptions, address[] addressOptions, address[] watchers);
- function finalizeRequest(uint ticketID) public{
- // if response time window is over or all delegates have voted,
- // anyone can finalize the request to trigger the event
- RequestTicket storage ticket = requestTickets[ticketID];
- if(!ticket.finalized){
- uint totalEligibleWeight;
- address watcher;
- //uint WEIGHTS[0];
- //uint WEIGHTS[1];
- uint[] memory WEIGHTS = new uint[](2);//0 weight of votes | 1 weight of rejections
- string[] memory stringOptions = new string[](hotSeats);
- uint[] memory uintOptions = new uint[](hotSeats);
- bool[] memory boolOptions = new bool[](hotSeats);
- address[] memory addressOptions = new address[](hotSeats);
- uint[] memory optionWeights = new uint[](hotSeats);
- address[] memory watchers = new address[](hotSeats);// LAZY UI data
- //uint options;
- uint[] memory OPT = new uint[](2);//0= number of options, 1=top Option
- //uint weight;
- //uint topOption;
- uint opt;
- for(uint chair = 0; chair < hotSeats; chair+=1){
- watcher = chairsCandidate[chair];
- watchers[chair] = watcher;
- //weight = totalShares[watcher];
- if( !frausted(watcher) && timeSeated[watcher] <= ticket.timeRequested ){
- totalEligibleWeight += totalShares[watcher];
- if(ticket.poll.voted[watcher]){
- WEIGHTS[0] += totalShares[watcher];
- //check to see if chosen option already is accounted for, if so, add weight to it.
- for(opt = 0; opt<OPT[0]; opt+=1){
- if( (ticket.poll.dataType == 0 && compareStrings(stringOptions[opt],ticket.poll.stringVotes[watcher]) ) ||
- (ticket.poll.dataType == 1 && uintOptions[opt] == ticket.poll.uintVotes[watcher]) ||
- (ticket.poll.dataType == 2 && boolOptions[opt] == ticket.poll.boolVotes[watcher]) ||
- (ticket.poll.dataType == 3 && addressOptions[opt] == ticket.poll.addressVotes[watcher])
- ){
- optionWeights[opt] += totalShares[watcher];
- if(optionWeights[opt] > optionWeights[OPT[1]]){
- OPT[1] = opt;
- }
- break;
- }
- }
- //add new unique option
- if(opt == OPT[0]){
- if(ticket.poll.dataType == 0){
- stringOptions[OPT[0]] = ticket.poll.stringVotes[watcher];
- }else if(ticket.poll.dataType == 1){
- uintOptions[OPT[0]] = ticket.poll.uintVotes[watcher];
- }else if(ticket.poll.dataType == 2){
- boolOptions[OPT[0]] = ticket.poll.boolVotes[watcher];
- }else if(ticket.poll.dataType == 3){
- addressOptions[OPT[0]] = ticket.poll.addressVotes[watcher];
- }
- optionWeights[OPT[0]] = totalShares[watcher];
- OPT[0]+=1;
- }
- }else if(ticket.poll.rejected[watcher]){
- WEIGHTS[1] += totalShares[watcher];
- }
- }
- }
- if( totalEligibleWeight == (WEIGHTS[1] + WEIGHTS[0]) || now > ticket.timeRequested+oracleConfigurations[REVEAL_TIME_WINDOW]+oracleConfigurations[COMMIT_TIME_WINDOW] ){
- bool rejected;
- if( WEIGHTS[1] > optionWeights[OPT[1]] ){
- rejected = true;
- }
- //dish out the rewards
- earningsPerShare[ORACLE] += ticket.serviceFee * scaleFactor / totalShares[ORACLE];
- earningsPerWatcher += ticket.txCoverageFee / totalWatchers;
- //write results in stone
- if(rejected){
- ticket.rejected = true;
- }else{
- uint8 dataType = ticket.poll.dataType;
- if(dataType == 0){
- ticket.resolvedString = stringOptions[OPT[1]];
- }else if(dataType == 1){
- ticket.resolvedUint = uintOptions[OPT[1]];
- }else if(dataType == 2){
- ticket.resolvedBool = boolOptions[OPT[1]];
- }else if(dataType == 3){
- ticket.resolvedAddress = addressOptions[OPT[1]];
- }
- }
- ticket.finalized = true;
- EMIT_FinalizeRequestData(ticket);
- emit FinalizedRequestOptions( stringOptions, uintOptions, boolOptions, addressOptions, watchers);
- //return results to requestor
- if( Common.isContract(ticket.sender) && ticket.needsResponse){
- sendOracleResponse(ticket);
- }
- }else{
- revert();
- }
- }
- }
- event FinalizedRequestTicketData(uint ticketID, string query, uint8 dataType, bool rejected, string resolvedString, uint resolvedUint, bool resolvedBool, address resolvedAddress);
- function EMIT_FinalizeRequestData(RequestTicket storage ticket) internal{
- FinalizedRequestTicketData(ticket.ID, ticket.query, ticket.poll.dataType, ticket.rejected, ticket.resolvedString, ticket.resolvedUint, ticket.resolvedBool, ticket.resolvedAddress);
- }
- function sendOracleResponse(RequestTicket memory ticket) internal{
- address(ticket.sender).call(abi.encodeWithSignature("receiveOracleResponse(bool,string,uint,bool,address)",ticket.rejected, ticket.resolvedString,ticket.resolvedUint,ticket.resolvedBool,ticket.resolvedAddress ) );
- }
- function cashout(address[] memory pools) public{
- address payable sender = msg.sender;
- for(uint p; p < pools.length; p+=1){
- update(pools[p], sender);
- }
- uint ETH = earnings[sender];
- earnings[sender] = 0;
- sender.transfer( ETH );
- }
- function runWatcherPayroll(address watcher) public{
- update(ORACLE, addressPayable(watcher) );
- updateWatcherTxEarnings(addressPayable(watcher) );
- }
- function tryToPunish(uint[] memory tickets, address[] memory watchers) public{
- freezeNoncommits(tickets, watchers);
- freezeUnrevealedCommits(tickets, watchers);
- freezeWrongWatchers(tickets, watchers);
- }
- event FreezeNoncommits(uint ticketID, address watcher);
- function freezeNoncommits(uint[] memory tickets, address[] memory watchers) public{
- // get them while they're still at the round table and we're in the reveal phase of a ticket
- for(uint i; i<watchers.length; i+=1){
- if( candidatesChair[watchers[i]] < hotSeats &&
- !requestTickets[ tickets[i] ].poll.committed[ watchers[i] ] &&
- now > requestTickets[ tickets[i] ].timeRequested + oracleConfigurations[COMMIT_TIME_WINDOW] &&
- now <= requestTickets[ tickets[i] ].timeRequested + oracleConfigurations[COMMIT_TIME_WINDOW] + oracleConfigurations[REVEAL_TIME_WINDOW]
- ){
- if(punish(tickets[i] , watchers[i]) ){
- emit FreezeNoncommits(tickets[i] , watchers[i]);
- }
- }
- }
- }
- event FreezeUnrevealedCommits(uint ticketID, address watcher);
- function freezeUnrevealedCommits(uint[] memory tickets, address[] memory watchers) public{
- // get them if they made a commit, but did not reveal it after the reveal window is over
- for(uint i; i<watchers.length; i+=1){
- if( requestTickets[ tickets[i] ].poll.committed[ watchers[i] ] &&
- !requestTickets[ tickets[i] ].poll.revealed[ watchers[i] ] &&
- now > requestTickets[ tickets[i] ].timeRequested + oracleConfigurations[COMMIT_TIME_WINDOW] + oracleConfigurations[REVEAL_TIME_WINDOW]
- ){
- if(punish(tickets[i] , watchers[i]) ){
- emit FreezeUnrevealedCommits(tickets[i] , watchers[i]);
- }
- }
- }
- }
- event FreezeWrongWatchers(uint ticketID, address watcher);
- function freezeWrongWatchers(uint[] memory tickets, address[] memory watchers) public{
- // get them if the ticket is finalized and their vote doesn't match the resolved answer
- uint ticket;
- address watcher;
- for(uint i; i<watchers.length; i+=1){
- ticket = tickets[i];
- watcher = watchers[i];
- if( requestTickets[ ticket ].finalized &&
- (
- (requestTickets[ ticket ].poll.dataType == 0 && !compareStrings(requestTickets[ ticket ].resolvedString, requestTickets[ ticket ].poll.stringVotes[ watcher ] ))||
- (requestTickets[ ticket ].poll.dataType == 1 && requestTickets[ ticket ].resolvedUint != requestTickets[ ticket ].poll.uintVotes[ watcher ] )||
- (requestTickets[ ticket ].poll.dataType == 2 && requestTickets[ ticket ].resolvedBool != requestTickets[ ticket ].poll.boolVotes[ watcher ] )||
- (requestTickets[ ticket ].poll.dataType == 3 && requestTickets[ ticket ].resolvedAddress != requestTickets[ ticket ].poll.addressVotes[ watcher ] )
- )
- ){
- if(punish(ticket , watcher)){
- emit FreezeWrongWatchers(ticket , watcher);
- }
- }
- }
- }
- event Punish(uint thatOutTime, bool freshFreeze, bool knockOff);
- function punish(uint ticketID, address watcher) internal returns(bool punished){
- if(!requestTickets[ticketID].punished[watcher] && timeSeated[watcher] <= requestTickets[ ticketID ].timeRequested ){
- frozen[watcher] = true;
- bool freshFreeze;
- bool knockOff;
- if(timeWhenThawedOut[watcher] > now){
- timeWhenThawedOut[watcher] += oracleConfigurations[FREEZE_TIMEOUT];
- }else{
- timeWhenThawedOut[watcher] = now + oracleConfigurations[FREEZE_TIMEOUT];
- freshFreeze = true;
- if(isWatcher(watcher)){
- //###
- removeShares(ORACLE, watcher, totalShares[watcher]);
- knockOff = true;
- }
- }
- emit Punish(timeWhenThawedOut[watcher], freshFreeze, knockOff);
- return true;
- }
- return false;
- }
- event Thaw(address candidate, bool seated);
- function thaw(address candidate, bool _assert) public{
- if( now >= timeWhenThawedOut[candidate] ){
- bool seated;
- frozen[candidate] = false;
- if( candidatesChair[candidate] < hotSeats && !paused[candidate]){
- //###
- addShares(ORACLE, candidate, totalShares[candidate]);
- seated = true;
- }else if( _assert ){
- seated = assertCandidate(candidate);
- }
- emit Thaw(candidate, seated);
- }else{
- revert();
- }
- }
- event PauseOut(address sender, bool wasWatcher);
- function pauseOut() public{
- address sender = msg.sender;
- bool wasWatcher;
- if(isWatcher(sender)){
- wasWatcher = true;
- //###
- removeShares(ORACLE, sender, totalShares[sender]);
- }
- paused[sender] = true;
- emit PauseOut(sender, wasWatcher);
- }
- event Unpause(address sender, bool seated);
- function unpause(bool _assert) public{
- address sender = msg.sender;
- paused[sender] = false;
- bool seated;
- if( candidatesChair[sender] < hotSeats && !frozen[sender]){
- //###
- addShares(ORACLE, sender, totalShares[sender]);
- seated = true;
- }else if( _assert ){
- seated = assertCandidate(sender);
- }
- emit Unpause(sender, seated);
- }
- event UpdateRoundTable(uint newTotalHotSeats);
- function updateRoundTable(uint seats) public{
- // update hotSeats up and down.
- address candidate;
- for(uint s; s<seats; s+=1){
- if( oracleConfigurations[ROUNDTABLE_SEATS] > hotSeats ){
- candidate = chairsCandidate[hotSeats];
- if(candidate == address0){
- break;
- }else{
- //###
- addShares(ORACLE, candidate, totalShares[candidate]);
- hotSeats += 1;
- }
- }
- if( oracleConfigurations[ROUNDTABLE_SEATS] < hotSeats ){
- candidate = chairsCandidate[hotSeats-1];
- //###
- removeShares(ORACLE, candidate, totalShares[candidate]);
- hotSeats -= 1;
- }
- if( oracleConfigurations[ROUNDTABLE_SEATS] == hotSeats ){break;}
- }
- emit UpdateRoundTable(hotSeats);
- }
- function viewRequestTickets(uint[] memory ticketIDs) public view returns(
- address[] memory sender,
- string[] memory query,
- uint[] memory timeRequested,
- bool[] memory finalized,
- uint[] memory txCoverageFeePaid,
- uint[] memory serviceFeePaid,
- bool[] memory rejected,
- string[] memory resolvedString,
- uint[] memory resolvedUint,
- bool[] memory resolvedBool,
- address[] memory resolvedAddress,
- uint8[] memory dataType){
- uint L = ticketIDs.length;
- sender = new address[](L);
- query = new string[](L);
- timeRequested = new uint[](L);
- finalized = new bool[](L);
- txCoverageFeePaid = new uint[](L);
- serviceFeePaid = new uint[](L);
- rejected = new bool[](L);
- resolvedString = new string[](L);
- resolvedUint = new uint[](L);
- resolvedBool = new bool[](L);
- resolvedAddress = new address[](L);
- dataType = new uint8[](L);
- for(uint t; t<L;t+=1){
- sender[t] = requestTickets[t].sender;
- query[t] = requestTickets[t].query;
- timeRequested[t] = requestTickets[t].timeRequested;
- finalized[t] = requestTickets[t].finalized;
- txCoverageFeePaid[t] = requestTickets[t].txCoverageFee;
- serviceFeePaid[t] = requestTickets[t].serviceFee;
- rejected[t] = requestTickets[t].rejected;
- resolvedString[t] = requestTickets[t].resolvedString;
- resolvedUint[t] = requestTickets[t].resolvedUint;
- resolvedBool[t] = requestTickets[t].resolvedBool;
- resolvedAddress[t] = requestTickets[t].resolvedAddress;
- dataType[t] = requestTickets[t].poll.dataType;
- }
- //return (ticket.sender, ticket.query,ticket.timeRequested,ticket.finalized,ticket.ETH,ticket.rejected,ticket.resolvedString,ticket.resolvedUint,ticket.resolvedBool,ticket.resolvedAddress,ticket.poll.dataType);
- }
- function viewYourCandidates(address you)public view returns(uint[] memory dividends, uint[] memory seat, bool[] memory isFrozen, bool[] memory isPaused){
- uint L = yourBacking[you].length;
- dividends = new uint[](L);
- seat = new uint[](L);
- isFrozen = new bool[](L);
- isPaused = new bool[](L);
- uint owedPerShare;// = earningsPerShare[pool] - payouts[pool][account];
- uint newMoney;// = shares[pool][account] * owedPerShare;
- address candidate;
- for(uint c;c<L;c+=1){
- candidate = yourBacking[you][c];
- owedPerShare = earningsPerShare[candidate] - payouts[candidate][you];
- newMoney = shares[candidate][you] * owedPerShare;
- dividends[c] = newMoney;
- seat[c] = candidatesChair[candidate];
- isFrozen[c] = frozen[candidate];
- isPaused[c] = paused[candidate];
- }
- }
- function compareStrings(string memory a, string memory b) public pure returns (bool) {
- return (keccak256(abi.encodePacked((a))) == keccak256(abi.encodePacked((b))) );
- }
- function compareBytes(bytes memory a, bytes memory b) public pure returns (bool) {
- return (keccak256(abi.encodePacked((a))) == keccak256(abi.encodePacked((b))) );
- }
- function accountData(address account) public view returns(
- uint _resolveWeight,
- uint _weightLocked,
- uint _candidatesChair,
- uint _timeSeated,
- bool _frozen,
- uint _timeWhenThawedOut,
- bool _paused,
- bool _hasChair,
- uint _earnings,
- uint _totalShares,
- uint _txCoverageFeeEarnings
- ){
- _resolveWeight = resolveWeight[account];
- _weightLocked = weightLocked[account];
- _candidatesChair = candidatesChair[account];
- _timeSeated = timeSeated[account];
- _frozen = frozen[account];
- _timeWhenThawedOut = timeWhenThawedOut[account];
- _paused = paused[account];
- _hasChair = hasChair[account];
- _earnings = earnings[account];
- _totalShares = totalShares[account];
- uint txCoverageFeeEarnings;
- if( !isWatcher(account) ){
- txCoverageFeeEarnings = earningsPerWatcher - watcherPayouts[account];
- }
- _txCoverageFeeEarnings = txCoverageFeeEarnings;
- }
- }
- abstract contract OracleInterfacingContract{
- function receiveOracleResponse(bool rejected, string calldata STRING, uint UINT, bool BOOL, address ADDRESS) external virtual returns(bool);
- }
- abstract contract ResolveToken{
- function transfer(address _to, uint256 _value) public virtual returns (bool);
- }
- /**
- * @title Common
- * @dev Math operations with safety checks that throw on error
- */
- library Common {
- /**
- * @dev Substracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
- */
- function subtract(uint256 a, uint256 b) internal pure returns (uint256) {
- assert(b <= a);
- return a - b;
- }
- //assemble the given address bytecode. If bytecode exists then the _addr is a contract.
- function isContract(address _addr) public view returns (bool is_contract) {
- uint length;
- assembly {
- //retrieve the size of the code on target address, this needs assembly
- length := extcodesize(_addr)
- }
- if(length>0) {
- return true;
- }else {
- return false;
- }
- }
- }
Add Comment
Please, Sign In to add comment