Skip to content

Commit

Permalink
council flag and 2/3 checks
Browse files Browse the repository at this point in the history
  • Loading branch information
Swastik47 authored and swastikc780 committed Jul 24, 2024
1 parent 58cae6c commit df65ecc
Show file tree
Hide file tree
Showing 9 changed files with 186 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,7 @@ public void migrateOldHashToNewHash(String oldHash, String newHash){
proposalBudgets.set(newHash,totalBudget);
}



//EventLogs
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ public class Constants {
public static final String STATE = "state";
public static final Address SYSTEM_ADDRESS = Address.fromString("cx0000000000000000000000000000000000000000");



public static final int sICXICXPoolID = 1;
public static final int sICXBNUSDPoolID = 2;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -723,11 +723,23 @@ public void voteProposal(String ipfsKey, String vote, String voteReason, @Option
TAG + ": Proposals can be voted only on Voting Period.");
Address caller = Context.getCaller();
PReps pReps = new PReps();
Context.require(ArrayDBUtils.containsInArrayDb(caller, pReps.validPreps),

// ArrayDB<String> callLocation = pReps.validPreps if councilFlag == false else callLocation = councilDb.abc

List<Address> callLocation;
if (getCouncilFlag()) {
callLocation = getCouncilManagers();
} else {
callLocation = ArrayDBUtils.arrayDBtoList(pReps.validPreps);
}

Context.require(ArrayDBUtils.containsInList(caller, callLocation),
TAG + ": Voting can only be done by registered P-Reps.");
Context.require(List.of(APPROVE, REJECT, ABSTAIN).contains(vote),
TAG + ": Vote should be either _approve, _reject or _abstain");

//Context.require(hasTwoThirdsMajority(?,?))

Map<String, Object> proposalDetails = getProposalDetails(ipfsKey);
String proposalPrefix = proposalPrefix(ipfsKey);
String status = (String) proposalDetails.get(STATUS);
Expand Down Expand Up @@ -976,10 +988,23 @@ public void voteProgressReport(String reportKey, String voteReason, MilestoneVot
TAG + ": Progress Reports can be voted only on Voting Period.");
Address caller = Context.getCaller();
PReps pReps = new PReps();

// ArrayDB<String> callLocation = pReps.validPreps if councilFlag == false else callLocation = councilDb.abc

List<Address> callLocation;
if (getCouncilFlag()) {
callLocation = getCouncilManagers();
} else {
callLocation = ArrayDBUtils.arrayDBtoList(pReps.validPreps);
}

Context.require(!ArrayDBUtils.containsInArrayDb(caller, blockAddresses),
TAG + ": You are blocked from CPS.");
Context.require(ArrayDBUtils.containsInArrayDb(caller, pReps.validPreps),
Context.require(ArrayDBUtils.containsInList(caller, callLocation),
TAG + ": Voting can only be done by registered P-Reps.");

//Context.require(hasTwoThirdsMajority(?,?))

String progressReportPrefix = progressReportPrefix(reportKey);
ArrayDB<Integer> submittedMilestones = milestoneSubmitted.at(progressReportPrefix);// CAN TAKE FROM READONLY METHOD
for (MilestoneVoteAttributes milestoneVote : votes) {
Expand Down Expand Up @@ -2656,6 +2681,39 @@ public Map<String, Object> getProposalsHistory(@Optional int startIndex) {
return milestoneIdList;
}

private boolean hasTwoThirdsMajority(String key, boolean isMilestone) {
//can also use if else if this doesnt work as intended

//error: milestonedb doesnt have total votes or voters

Map<String, Object> milestoneDbData = MilestoneDb.getDataFromMilestoneDB(key);
BigInteger totalVotes = isMilestone ? (BigInteger)milestoneDbData.get(TOTAL_VOTES) : ProgressReportDataDb.totalVotes.at(key).getOrDefault(BigInteger.ZERO);
int totalVoters = isMilestone ? (Integer)milestoneDbData.get(TOTAL_VOTERS) : ProgressReportDataDb.totalVoters.at(key).getOrDefault(0);

BigInteger approveVotes = isMilestone ? MilestoneDb.approvedVotes.at(key).getOrDefault(BigInteger.ZERO) : ProgressReportDataDb.approvedVotes.at(key).getOrDefault(BigInteger.ZERO);
int approveVoters = isMilestone ? MilestoneDb.approveVoters.at(key).size() : ProgressReportDataDb.approveVoters.at(key).size();

//need to give vote weights = 100 (arbitrary)
boolean voteWeightCheck = approveVotes.multiply(BigInteger.valueOf(3)).compareTo(totalVotes.multiply(BigInteger.valueOf(2))) >= 0;
boolean voterCountCheck = approveVoters * 3 >= totalVoters * 2;

return voteWeightCheck && voterCountCheck;
}

// @External(readonly=true)
// private Address[] getCouncilManagers() {
// return call(Address[].class, cpfTreasury.get(), "getCouncilManagers");
// }

@SuppressWarnings({ "unchecked"})
private List<Address> getCouncilManagers() {
return callScore(List.class, getCpfTreasuryScore(), "getCouncilManagers");
}

private boolean getCouncilFlag() {
return callScore(boolean.class, getCpfTreasuryScore(), "getCouncilFlag");
}

// =====================================TEMPORARY MIGRATIONS METHODS===============================================

@External
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,17 @@ public class MilestoneDb {

public static final BranchDB<String, BranchDB<Address, DictDB<String, Integer>>> votersListIndices = Context.newBranchDB(VOTERS_LIST_INDEXES, Integer.class);

public static final BranchDB<String, VarDB<Boolean>> majorityFlag = Context.newBranchDB(MAJORITY_FLAG, Boolean.class);

public static void addDataToMilestoneDb(CPSCoreInterface.MilestonesAttributes milestoneData, String prefix) {
id.at(prefix).set(milestoneData.id);
approvedVotes.at(prefix).set(BigInteger.ZERO);
rejectedVotes.at(prefix).set(BigInteger.ZERO);
completionPeriod.at(prefix).set(milestoneData.completionPeriod);
budget.at(prefix).set(milestoneData.budget);

majorityFlag.at(prefix).set(false);

}

public static Map<String, Object> getDataFromMilestoneDB(String prefix) {
Expand All @@ -46,7 +50,10 @@ public static Map<String, Object> getDataFromMilestoneDB(String prefix) {
Map.entry(TOTAL_VOTERS, ProgressReportDataDb.totalVoters.at(progressReportPrefix(reportHash)).getOrDefault(0)),
Map.entry(APPROVE_VOTERS, approveVoters.at(prefix).size()),
Map.entry(REJECT_VOTERS, rejectVoters.at(prefix).size()),
Map.entry(EXTENSION_FLAG, extensionFlag.at(prefix).getOrDefault(false)));
Map.entry(EXTENSION_FLAG, extensionFlag.at(prefix).getOrDefault(false)),

Map.entry(MAJORITY_FLAG, majorityFlag.at(prefix).getOrDefault(false)));

}

public static String progressReportPrefix(String progressHash) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ public class ProposalDataDb {
public static final BranchDB<String, VarDB<Integer>> proposalPeriod = Context.newBranchDB(PROPOSAL_PERIOD, Integer.class);
public static final BranchDB<String, ArrayDB<Integer>> milestoneIds = Context.newBranchDB("milestoneIds", Integer.class);

public static final BranchDB<String, VarDB<Boolean>> majorityFlag = Context.newBranchDB(MAJORITY_FLAG, Boolean.class);
public static final BranchDB<String, VarDB<Boolean>> councilFlag = Context.newBranchDB(COUNCIL_FLAG, Boolean.class);


public static void addDataToProposalDB(ProposalAttributes proposalData, String prefix) {
ipfsHash.at(prefix).set(proposalData.ipfs_hash);
projectTitle.at(prefix).set(proposalData.project_title);
Expand All @@ -69,6 +73,9 @@ public static void addDataToProposalDB(ProposalAttributes proposalData, String p
milestoneCount.at(prefix).set(proposalData.milestoneCount);
isMilestone.at(prefix).set(true);

majorityFlag.at(prefix).set(false);
councilFlag.at(prefix).set(false);

}

public static void updatePercentageCompleted(String prefix, int percentage) {
Expand Down Expand Up @@ -96,7 +103,11 @@ public static Map<String, Object> getDataFromProposalDB(String prefix) {
Map.entry(IS_MILESTONE,isMilestone.at(prefix).getOrDefault(false)),
Map.entry(PERCENTAGE_COMPLETED,percentageCompleted.at(prefix).getOrDefault(0)),
Map.entry(SUBMIT_PROGRESS_REPORT, submitProgressReport.at(prefix).getOrDefault(false)),
Map.entry(PROPOSAL_PERIOD,proposalPeriod.at(prefix).getOrDefault(0)));
Map.entry(PROPOSAL_PERIOD,proposalPeriod.at(prefix).getOrDefault(0)),

Map.entry(MAJORITY_FLAG, majorityFlag.at(prefix).getOrDefault(false)),
Map.entry(COUNCIL_FLAG, councilFlag.at(prefix).getOrDefault(false)));

}

public static int getMilestoneCount(String prefix) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,10 @@ public class Constants {
public static final Integer MILESTONE_REPORT_APPROVED = 3;
public static final Integer MILESTONE_REPORT_NOT_COMPLETED = 4;

// new flags
public static final String MAJORITY_FLAG = "majority_flag";
public static final String COUNCIL_FLAG = "council_flag";


public static final BigInteger TOTAL_PERIOD = BigInteger.valueOf(30);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
import com.iconloop.score.test.TestBase;
import community.icon.cps.score.cpscore.utils.Constants;
import community.icon.cps.score.lib.interfaces.CPSCoreInterface;
import community.icon.cps.score.lib.interfaces.CPSCoreInterface.ProgressReportAttributes;
import community.icon.cps.score.lib.interfaces.CPSCoreInterface.ProposalAttributes;

import org.junit.jupiter.api.*;
import org.junit.jupiter.api.function.Executable;
import org.mockito.MockedStatic;
Expand All @@ -21,10 +24,13 @@
import java.util.List;
import java.util.Map;

import static community.icon.cps.score.cpscore.db.ProposalDataDb.councilFlag;
import static community.icon.cps.score.cpscore.utils.Constants.*;
import static community.icon.cps.score.lib.interfaces.CPSCoreInterface.ProgressReportAttributes;
import static community.icon.cps.score.lib.interfaces.CPSCoreInterface.ProposalAttributes;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.*;
Expand Down Expand Up @@ -517,6 +523,7 @@ void updateNextBlock() {

@Test
@DisplayName("vote approve then change it to reject")
//changes to this file too?
void voteProposal() {
submitAndSponsorVote();
contextMock.when(caller()).thenReturn(owner.getAddress());
Expand Down Expand Up @@ -2046,6 +2053,75 @@ void submitProgressReportBeforeDeadline() {

}

//begin
@Test
void testhasTwoThirdsMajority(){
String key="test";

doReturn(BigInteger.valueOf(15)).when(scoreSpy).getSponsorBondPercentage();
registerPrepsMethod();


//need attributes?

//set flag to true for mock test
//doReturn(true).when(cpsScore).call(Boolean.class, ((Object) cpfTreasury).get(), "getCouncilFlag");
boolean councilFlag = true;
// sponsor address sponsor voter valid prep ma exist huna paryo
//votes 3 wota weight 100= constant 100x10=1000

cpsScore.invoke(owner, "setMilestoneVotes", key, BigInteger.valueOf(1000), 10);
cpsScore.invoke(owner, "setApprovedVotes", key, BigInteger.valueOf(700), 7);

Boolean result = call(Boolean.class, cpsScore.getAddress(), "hasTwoThirdsMajority", key);
assertTrue(result);

contextMock.when(caller()).thenReturn(testingAccount.getAddress());
cpsScore.invoke(testingAccount, "setMilestoneVotes", key, BigInteger.valueOf(1000), 10);
cpsScore.invoke(testingAccount, "setApprovedVotes", key, BigInteger.valueOf(300), 3);

result = call(Boolean.class, cpsScore.getAddress(), "hasTwoThirdsMajority", key);
assertFalse(result, "Should meet 2/3 majority");

//flag to false
// doReturn(false).when(cpsScore).call(Boolean.class, ((Object) cpfTreasury).get(), "getCouncilFlag");
councilFlag = false;

contextMock.when(caller()).thenReturn(testingAccount1.getAddress());
cpsScore.invoke(testingAccount1, "setMilestoneVotes", key, BigInteger.valueOf(1000), 10);
cpsScore.invoke(testingAccount1, "setApprovedVotes", key, BigInteger.valueOf(700), 7);

result = call(Boolean.class, cpsScore.getAddress(), "hasTwoThirdsMajority", key);
assertTrue(result);

contextMock.when(caller()).thenReturn(testingAccount.getAddress());
cpsScore.invoke(testingAccount2, "setMilestoneVotes", key, BigInteger.valueOf(1000), 10);
cpsScore.invoke(testingAccount2, "setApprovedVotes", key, BigInteger.valueOf(300), 3);

result = call(Boolean.class, cpsScore.getAddress(), "hasTwoThirdsMajority", key);
assertFalse(result, "Should meet 2/3 majority");

}

private Boolean call(Class<Boolean> class1, Address address, String string, String key) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'call'");
}

void setMilestoneVotes(String key, BigInteger totalVotes, int totalVoters) {
cpsScore.invoke(owner, "setTotalVotes", key, totalVotes, totalVoters, true);
}

void setProposalVotes(String key, BigInteger totalVotes, int totalVoters) {
cpsScore.invoke(owner, "setTotalVotes", key, totalVotes, totalVoters, false);
}

void setApprovedVotes(String key, BigInteger approvedVotes, int approveVoters, boolean isMilestone) {
cpsScore.invoke(owner, "setApprovedVotes", key, approvedVotes, approveVoters, isMilestone);
}


//end

@Test
void setSwapCount() {
Expand Down
18 changes: 18 additions & 0 deletions cps/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
## Getting Started

Welcome to the VS Code Java world. Here is a guideline to help you get started to write Java code in Visual Studio Code.

## Folder Structure

The workspace contains two folders by default, where:

- `src`: the folder to maintain sources
- `lib`: the folder to maintain dependencies

Meanwhile, the compiled output files will be generated in the `bin` folder by default.

> If you want to customize the folder structure, open `.vscode/settings.json` and update the related settings there.
## Dependency Management

The `JAVA PROJECTS` view allows you to manage your dependencies. More details can be found [here](https://github.com/microsoft/vscode-java-dependency#manage-dependencies).
5 changes: 5 additions & 0 deletions cps/src/App.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
public class App {
public static void main(String[] args) throws Exception {
System.out.println("Hello, World!");
}
}

0 comments on commit df65ecc

Please sign in to comment.