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

Dev add council flag by governance contract #33

Merged
Merged
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
22 changes: 12 additions & 10 deletions CPFTreasury/build.gradle
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version = '1.2.0'
version = '1.5.0'

dependencies {
// compileOnly 'foundation.icon:javaee-api:0.9.1'
Expand Down Expand Up @@ -31,27 +31,29 @@ deployJar {
lisbon {
uri = 'https://lisbon.net.solidwallet.io/api/v3'
nid = 0x2
to = 'cx3d4182c0e783b7ef97ba63409c4bdf808853bd9f'
}
local {
uri = 'http://localhost:9082/api/v3'
nid = 0x3
}
berlin {
uri = 'https://berlin.net.solidwallet.io/api/v3'
nid = 0x7
to = "cxd19ed92de2050a87c709097b6297aadf5f8d7432"
}

mainnet {
uri = 'https://ctz.solidwallet.io/api/v3'
nid = 0x1
to = 'cxdca1178010b5368aea929ad5c06abee64b91acc2'
}
devnet{
uri = "https://tt.net.solidwallet.io/api/v3"
nid = 0x3
to = "cx0d0638e5764ede3ed2c9eadd179bc67785868842"
}

}
keystore = rootProject.hasProperty('keystoreName') ? "$keystoreName" : ''
password = rootProject.hasProperty('keystorePass') ? "$keystorePass" : ''
parameters {
arg("cpsScore", "cx5100c8b221cc373939d8a720ecfbd90440c75ed3")
}
}


test {
useJUnitPlatform()
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,14 @@ public class CPFTreasury extends SetterGetter implements CPFTreasuryInterface {
public static final VarDB<Address> sICXScore = Context.newVarDB(SICX_SCORE, Address.class);
public static final VarDB<Address> routerScore = Context.newVarDB(ROUTER_SCORE, Address.class);
public static final VarDB<Address> oracleAddress = Context.newVarDB(ORACLE_ADDRESS, Address.class);

private final ArrayDB<String> proposalsKeys = Context.newArrayDB(PROPOSALS_KEYS, String.class);
private final DictDB<String, BigInteger> proposalBudgets = Context.newDictDB(PROPOSAL_BUDGETS, BigInteger.class);

private final VarDB<BigInteger> treasuryFund = Context.newVarDB(TREASURY_FUND, BigInteger.class);
private final VarDB<BigInteger> emergencyFund = Context.newVarDB(EMERGENCY_FUND, BigInteger.class);
public static final DictDB<String, BigInteger> rewardPool = Context.newDictDB(REWARD_POOL, BigInteger.class);

private final VarDB<BigInteger> treasuryFundbnUSD = Context.newVarDB(TREASURY_FUND_BNUSD, BigInteger.class);

private final VarDB<Integer> swapState = Context.newVarDB(SWAP_STATE, Integer.class);
Expand All @@ -39,14 +43,29 @@ public class CPFTreasury extends SetterGetter implements CPFTreasuryInterface {
private final VarDB<Boolean> swapFlag = Context.newVarDB(SWAP_FLAG, Boolean.class);
private final VarDB<BigInteger> swapLimitAmount = Context.newVarDB(SWAP_LIMIT_AMOUNT, BigInteger.class);

public static final VarDB<Boolean> councilFlag = Context.newVarDB(COUNCIL_FLAG, Boolean.class);
public static final ArrayDB<Address> councilManagers = Context.newArrayDB(COUNCIL_MANAGERS, Address.class);

public static final VarDB<Integer> councilManagerRewardPercentage = Context.newVarDB(COUNCIL_MANAGERS_REWARD_PERCENTAGE, Integer.class);
public static final DictDB<Address, BigInteger> councilManagersReward = Context.newDictDB(COUNCIL_MANAGERS_REWARD, BigInteger.class);


public CPFTreasury(@Optional Address cpsScore) {
if (treasuryFund.get() == null) {
treasuryFund.set(BigInteger.valueOf(1000000).multiply(EXA));
treasuryFund.set(BigInteger.valueOf(5000000).multiply(EXA));
swapCount.set(SwapReset);
swapState.set(SwapReset);
swapFlag.set(false);
treasuryFundbnUSD.set(BigInteger.valueOf(5000000).multiply(EXA));
CPFTreasury.cpsScore.set(cpsScore);
}

councilFlag.set(true);
councilManagers.add(Address.fromString("hxd4eb0a6c591b5e7a76e9a6677da055ebfdd897da"));
councilManagers.add(Address.fromString("hx9fa9d224306b0722099d30471b3c2306421aead7"));
councilManagers.add(Address.fromString("hx03907c67a68e8d6948cff58f49d39b3d7c8d95ad"));
councilManagerRewardPercentage.set(0);

}

private boolean proposalExists(String ipfsKey) {
Expand Down Expand Up @@ -103,8 +122,7 @@ private void burn(BigInteger amount) {
@Override
@External(readonly = true)
public Map<String, BigInteger> getTotalFunds() {
return Map.of(ICX, Context.getBalance(Context.getAddress()),
bnUSD, getBNUSDAvailableBalance());
return Map.of(ICX, Context.getBalance(Context.getAddress()), bnUSD, getBNUSDAvailableBalance());
}

@External(readonly = true)
Expand All @@ -117,22 +135,32 @@ public BigInteger getEmergencyFund() {
return getTotalFundBNUSD().get(EMERGENCY_FUND);
}

@External
public void setFundManagersRewards(int paymentPercentage) {
// validateGovernanceContract();
validateAdmins();
Context.require(paymentPercentage >= 0 && paymentPercentage <= 100, TAG + " :InvalidPercentage");
councilManagerRewardPercentage.set(paymentPercentage);
setRewardPool(INITIAL_FUND);
}

@External(readonly = true)
public int getFundManagersRewards() {
return councilManagerRewardPercentage.getOrDefault(0);
}

private Map<String, BigInteger> getTotalFundBNUSD() {
BigInteger bnusdBalance = (BigInteger) Context.call(balancedDollar.get(), "balanceOf", Context.getAddress());
BigInteger emergencyFund = this.emergencyFund.getOrDefault(BigInteger.ZERO);
BigInteger availableBalance = bnusdBalance.subtract(emergencyFund);
return Map.of(BNUSD_BALANCE, bnusdBalance,
EMERGENCY_FUND, emergencyFund,
AVAILABLE_BALANCE, availableBalance);
return Map.of(BNUSD_BALANCE, bnusdBalance, EMERGENCY_FUND, emergencyFund, AVAILABLE_BALANCE, availableBalance);
}

@Override
@External(readonly = true)
public Map<String, BigInteger> getRemainingSwapAmount() {
BigInteger maxCap = treasuryFundbnUSD.get();
return Map.of(MAX_CAP, maxCap,
REMAINING_TO_SWAP, maxCap.subtract(getBNUSDAvailableBalance()));
return Map.of(MAX_CAP, maxCap, REMAINING_TO_SWAP, maxCap.subtract(getBNUSDAvailableBalance()));
}

private void returnFundAmount(Address address, BigInteger value) {
Expand All @@ -143,9 +171,7 @@ private void returnFundAmount(Address address, BigInteger value) {

@Override
@External
public void transferProposalFundToCpsTreasury(String ipfsKey, int projectDuration,
Address sponsorAddress, Address contributorAddress,
String tokenFlag, BigInteger totalBudget) {
public void transferProposalFundToCpsTreasury(String ipfsKey, int projectDuration, Address sponsorAddress, Address contributorAddress, String tokenFlag, BigInteger totalBudget) {
validateCpsScore();
Context.require(!proposalExists(ipfsKey), TAG + ": Project already exists. Invalid IPFS Hash");
Context.require(tokenFlag.equals(bnUSD), TAG + ": " + tokenFlag + " is not supported. Only " + bnUSD + " token available.");
Expand Down Expand Up @@ -177,8 +203,7 @@ public void transferProposalFundToCpsTreasury(String ipfsKey, int projectDuratio

@Override
@External
public void updateProposalFund(String ipfsKey, @Optional String flag, @Optional BigInteger addedBudget,
@Optional int totalInstallmentCount) {
public void updateProposalFund(String ipfsKey, @Optional String flag, @Optional BigInteger addedBudget, @Optional int totalInstallmentCount) {
validateCpsScore();
Context.require(proposalExists(ipfsKey), TAG + ": IPFS hash does not exist.");
Context.require(flag != null && flag.equals(bnUSD), TAG + ": Unsupported token. " + flag);
Expand Down Expand Up @@ -274,7 +299,7 @@ private void swapIcxBnusd(BigInteger amount, BigInteger _minReceive) {
}
Context.call(amount, routerScore.get(), "route", path, _minReceive);
} catch (Exception e) {
Context.println("Ignoring Errors from Router. Error Message: " + e.getMessage());
Context.println("Ignoring Errors from Router. Error Message: " + e.getMessage());
}
}
}
Expand Down Expand Up @@ -332,7 +357,7 @@ public void withdrawFromEmergencyFund(BigInteger value, Address address, String
Address balancedDollar = CPFTreasury.balancedDollar.get();

Context.call(balancedDollar, TRANSFER, address, value, "".getBytes());
EmergencyFundTransferred(address, value,purpose);
EmergencyFundTransferred(address, value, purpose);
}


Expand Down Expand Up @@ -395,6 +420,66 @@ public void setOraclePercentageDifference(int value) {
oraclePerDiff.set(value);
}

@External
public void setRewardPool(String key) {
validateCpsScore();
Context.require(key.equals(INITIAL_FUND) || key.equals(FINAL_FUND), TAG + ": incorrectKeyForPool");
rewardPool.set(key, getTotalFundBNUSD().get(AVAILABLE_BALANCE));
}

@External(readonly = true)
public Map<String, BigInteger> getRewardPool() {
BigInteger finalFund = rewardPool.getOrDefault(FINAL_FUND, BigInteger.ZERO);
BigInteger initialFund = rewardPool.getOrDefault(INITIAL_FUND, BigInteger.ZERO);
BigInteger fundDiff = finalFund.subtract(initialFund);
BigInteger rewardPool = fundDiff.multiply(BigInteger.valueOf(getFundManagersRewards())).divide(BigInteger.valueOf(100));
return Map.of(INITIAL_FUND, initialFund, FINAL_FUND, finalFund, REWARD_POOL, rewardPool);
}

@External
public void distributeRewardToFundManagers() {
validateCpsScore();
if (getFundManagersRewards() > 0) {
try {
Map<String, BigInteger> rewardPool = getRewardPool();
BigInteger initialFund = rewardPool.get(INITIAL_FUND);
BigInteger finalFund = rewardPool.get(FINAL_FUND);

Context.require((initialFund.compareTo(BigInteger.ZERO) > 0 && finalFund.compareTo(BigInteger.ZERO) > 0), TAG + ": RewardPoolIsEmpty");

BigInteger rewardPoolAmount = rewardPool.get(REWARD_POOL);
int len = councilManagers.size();
BigInteger rewardAmount = rewardPoolAmount.divide(BigInteger.valueOf(len));

for (int i = 0; i < len; i++) {
Address manager = councilManagers.get(i);
councilManagersReward.set(manager, councilManagersReward.getOrDefault(manager, BigInteger.ZERO).add(rewardAmount));
FundManagerRewardSet(manager, rewardAmount);
}

} catch (Exception e) {
Context.println("Error in distributeRewardToFundManagers: " + e.getMessage());
}
setRewardPool(INITIAL_FUND);
}
}

@External(readonly = true)
public BigInteger getRewardAmountForManager(Address manager) {
return councilManagersReward.getOrDefault(manager, BigInteger.ZERO);
}

@External
public void claimFundManagerReward() {
Address manager = Context.getCaller();
BigInteger rewardAmount = councilManagersReward.getOrDefault(manager, BigInteger.ZERO);
Context.require(rewardAmount.compareTo(BigInteger.ZERO) > 0, TAG + ": No reward to claim.");

councilManagersReward.set(manager, BigInteger.ZERO);
Context.call(balancedDollar.get(), TRANSFER, manager, rewardAmount, "".getBytes());
FundManagerRewardClaimed(manager, rewardAmount);
}

@Override
@External(readonly = true)
public Map<String, Object> getProposalDetails(@Optional int startIndex, @Optional int endIndex) {
Expand Down Expand Up @@ -434,8 +519,7 @@ public void tokenFallback(Address _from, BigInteger _value, byte[] _data) {
Address sICX = sICXScore.get();
Address caller = Context.getCaller();

Context.require(caller.equals(bnUSDScore) || caller.equals(sICX), TAG +
" Only " + bnUSDScore + " and " + sICX + " can send tokens to CPF Treasury.");
Context.require(caller.equals(bnUSDScore) || caller.equals(sICX), TAG + " Only " + bnUSDScore + " and " + sICX + " can send tokens to CPF Treasury.");
if (caller.equals(sICX)) {
if (_from.equals(dexScore.get())) {
JsonObject swapICX = new JsonObject();
Expand All @@ -445,7 +529,6 @@ public void tokenFallback(Address _from, BigInteger _value, byte[] _data) {
Context.revert(TAG + ": sICX can be approved only from Balanced DEX.");
}
} else {

if (_data == null || new String(_data).equalsIgnoreCase("none")) {
_data = "{}".getBytes();
}
Expand Down Expand Up @@ -485,7 +568,7 @@ public void fallback() {
}

@External
public void migrateOldHashToNewHash(String oldHash, String newHash){
public void migrateOldHashToNewHash(String oldHash, String newHash) {
validateCpsScore();
int size = proposalsKeys.size();
for (int i = 0; i < size; i++) {
Expand All @@ -495,8 +578,8 @@ public void migrateOldHashToNewHash(String oldHash, String newHash){
}

BigInteger totalBudget = proposalBudgets.get(oldHash);
proposalBudgets.set(oldHash,null);
proposalBudgets.set(newHash,totalBudget);
proposalBudgets.set(oldHash, null);
proposalBudgets.set(newHash, totalBudget);
}


Expand Down Expand Up @@ -524,4 +607,12 @@ public void FundReceived(Address _sponsor_address, String note) {
@EventLog(indexed = 1)
public void EmergencyFundTransferred(Address _address, BigInteger _value, String _purpose) {
}

@EventLog(indexed = 1)
public void FundManagerRewardSet(Address _address, BigInteger _value) {
}

@EventLog(indexed = 1)
public void FundManagerRewardClaimed(Address _address, BigInteger _value) {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ public class Constants {
public static final String PROPOSALS_KEYS = "_proposals_keys";
public static final String TREASURY_FUND = "treasury_fund";
public static final String EMERGENCY_FUND = "emergencyFund";
public static final String REWARD_POOL = "rewardPool";

public static final String INITIAL_FUND = "initialFund";
public static final String FINAL_FUND = "finalFund";

public static final String AVAILABLE_BALANCE = "availableBalance";
public static final String TREASURY_FUND_BNUSD = "treasury_fund_bnusd";

Expand Down Expand Up @@ -49,6 +54,11 @@ public class Constants {
public static final String STATE = "state";
public static final Address SYSTEM_ADDRESS = Address.fromString("cx0000000000000000000000000000000000000000");

public static final String COUNCIL_FLAG = "council_flag";
public static final String COUNCIL_MANAGERS = "council_managers";
public static final String COUNCIL_MANAGERS_REWARD = "councilManagersReward";
public static final String COUNCIL_MANAGERS_REWARD_PERCENTAGE = "councilManagersRewardPercentage";

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

Expand Down
Loading