Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
lidangzzz committed May 30, 2023
1 parent cf0b3bc commit c4d58ae
Show file tree
Hide file tree
Showing 5 changed files with 195 additions and 65 deletions.
7 changes: 7 additions & 0 deletions darc-protocol/contracts/Dashboard/Dashboard.sol
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,11 @@ contract Dashboard is MachineStateManager {
function sumDividendWeightByTokenClass(uint256 tokenClassIndex) public view returns (uint256) {
return sumDividendWeightForTokenClass(false, tokenClassIndex);
}

/**
* Get the current dividend per unit
*/
function getCurrentDividendPerUnit() public view returns (uint256) {
return currentDividendPerUnit(false);
}
}
102 changes: 101 additions & 1 deletion darc-protocol/contracts/MachineStateManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pragma solidity ^0.8.9;
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "./MachineState.sol";
import "./Plugin/Plugin.sol";
import "./Utilities/ErrorMsg.sol";

// import openzeppelin upgradeable contracts safe math
import "@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol";
Expand Down Expand Up @@ -330,5 +331,104 @@ contract MachineStateManager {
return votingWeight;
}
}


/**
* Calculate the current dividend per unit
* @param bIsSandbox The flag to indicate whether is the sandbox
*/

function currentDividendPerUnit(bool bIsSandbox) public view returns(uint256) {
if (bIsSandbox) {
// make sure that the dividend per myriad per transaction is less than 1000
require(sandboxMachineState.machineStateParameters.dividendPermyriadPerTransaction < 1000,
ErrorMsg.By(15));

// make sure that cycle counter is less than the threashold
require(sandboxMachineState.machineStateParameters.dividendCycleCounter >=
sandboxMachineState.machineStateParameters.dividendCycleOfTransactions, ErrorMsg.By(16));

// 1. calculate the total amount of dividends to be offered
bool bIsValid = true;
uint256 totalDividends = 0;

(bIsValid, totalDividends) = SafeMathUpgradeable.tryMul(
sandboxMachineState.machineStateParameters.currentCashBalanceForDividends,
sandboxMachineState.machineStateParameters.dividendPermyriadPerTransaction);

(bIsValid, totalDividends) = SafeMathUpgradeable.tryDiv(
totalDividends,
1000);
require (bIsValid, ErrorMsg.By(12));

// 2. calculate the total dividends weight of all dividendable tokens
uint256 totalDividendsWeight = 0;

for (uint256 index=0; index < sandboxMachineState.tokenList.length; index++) {

if (sandboxMachineState.tokenList[index].bIsInitialized == false) {
break;
}

(bIsValid, totalDividendsWeight) = SafeMathUpgradeable.tryAdd(
totalDividendsWeight,
sumDividendWeightForTokenClass(bIsSandbox, index));
require(bIsValid, ErrorMsg.By(12));
}

// 3. calculate the cash dividend per unit
uint256 cashPerUnit = 0;
(bIsValid, cashPerUnit) = SafeMathUpgradeable.tryDiv(
totalDividends,
totalDividendsWeight);

return (cashPerUnit);
} else {
// make sure that the dividend per myriad per transaction is less than 1000
require(currentMachineState.machineStateParameters.dividendPermyriadPerTransaction < 1000,
ErrorMsg.By(15));

// make sure that cycle counter is less than the threashold
require(currentMachineState.machineStateParameters.dividendCycleCounter >=
currentMachineState.machineStateParameters.dividendCycleOfTransactions, ErrorMsg.By(16));

// 1. calculate the total amount of dividends to be offered
bool bIsValid = true;
uint256 totalDividends = 0;

(bIsValid, totalDividends) = SafeMathUpgradeable.tryMul(
currentMachineState.machineStateParameters.currentCashBalanceForDividends,
currentMachineState.machineStateParameters.dividendPermyriadPerTransaction);

(bIsValid, totalDividends) = SafeMathUpgradeable.tryDiv(
totalDividends,
1000);
require (bIsValid, ErrorMsg.By(12));

// 2. calculate the total dividends weight of all dividendable tokens
uint256 totalDividendsWeight = 0;

for (uint256 index=0; index < currentMachineState.tokenList.length; index++) {

if (currentMachineState.tokenList[index].bIsInitialized == false) {
break;
}

(bIsValid, totalDividendsWeight) = SafeMathUpgradeable.tryAdd(
totalDividendsWeight,
sumDividendWeightForTokenClass(bIsSandbox, index));
require(bIsValid, ErrorMsg.By(12));
}

// 3. calculate the cash dividend per unit
uint256 cashPerUnit = 0;
(bIsValid, cashPerUnit) = SafeMathUpgradeable.tryDiv(
totalDividends,
totalDividendsWeight);

return (cashPerUnit);
}
}



}
Original file line number Diff line number Diff line change
Expand Up @@ -28,41 +28,9 @@ contract OfferDividendsInstructions is MachineStateManager {

// 1. calculate the total amount of dividends to be offered
bool bIsValid = true;
uint256 totalDividends = 0;

(bIsValid, totalDividends) = SafeMathUpgradeable.tryDiv(
sandboxMachineState.machineStateParameters.currentCashBalanceForDividends,
1000);
require (bIsValid, ErrorMsg.By(12));

(bIsValid, totalDividends) = SafeMathUpgradeable.tryMul(
totalDividends,
sandboxMachineState.machineStateParameters.dividendPermyriadPerTransaction);

// 2. calculate the total dividends weight of all dividendable tokens
uint256 totalDividendsWeight = 0;
uint256 ithTotalWeights = 0;
for (uint256 index=0; index < sandboxMachineState.tokenList.length; index++) {
ithTotalWeights = 0;
if (sandboxMachineState.tokenList[index].bIsInitialized == false) {
break;
}
(bIsValid, ithTotalWeights) = SafeMathUpgradeable.tryMul(
sumDividendWeightForTokenClass(bIsSandbox, index),
sandboxMachineState.tokenList[index].dividendWeight);
require(bIsValid, ErrorMsg.By(12));

(bIsValid, totalDividendsWeight) = SafeMathUpgradeable.tryAdd(
totalDividendsWeight,
ithTotalWeights);
require(bIsValid, ErrorMsg.By(12));
}

// 3. calculate the cash dividend per unit
uint256 cashPerUnit = 0;
(bIsValid, cashPerUnit) = SafeMathUpgradeable.tryDiv(
totalDividends,
totalDividendsWeight);
uint256 cashPerUnit = currentDividendPerUnit(bIsSandbox);

// 4. calculate the cash dividend per unit for each token, add dividends to
// each address withdrawable balance
Expand All @@ -89,6 +57,11 @@ contract OfferDividendsInstructions is MachineStateManager {
cashPerUnit);
require(bIsValid, ErrorMsg.By(12));

(bIsValid, dividends) = SafeMathUpgradeable.tryMul(
dividends,
sandboxMachineState.tokenList[index].dividendWeight
);

// add the dividends to the withdrawable balance of the address
(bIsValid, sandboxMachineState.withdrawableDividendMap[owner]) = SafeMathUpgradeable.tryAdd(
sandboxMachineState.withdrawableDividendMap[owner],
Expand Down Expand Up @@ -181,14 +154,16 @@ contract OfferDividendsInstructions is MachineStateManager {
bool bIsValid = true;
uint256 totalDividends = 0;

(bIsValid, totalDividends) = SafeMathUpgradeable.tryMul(
currentMachineState.machineStateParameters.currentCashBalanceForDividends,
currentMachineState.machineStateParameters.dividendPermyriadPerTransaction);

(bIsValid, totalDividends) = SafeMathUpgradeable.tryDiv(
currentMachineState.machineStateParameters.currentCashBalanceForDividends,
totalDividends,
1000);
require (bIsValid, ErrorMsg.By(12));

(bIsValid, totalDividends) = SafeMathUpgradeable.tryMul(
totalDividends,
currentMachineState.machineStateParameters.dividendPermyriadPerTransaction);


// 2. calculate the total dividends weight of all dividendable tokens
uint256 totalDividendsWeight = 0;
Expand All @@ -210,10 +185,7 @@ contract OfferDividendsInstructions is MachineStateManager {
}

// 3. calculate the cash dividend per unit
uint256 cashPerUnit = 0;
(bIsValid, cashPerUnit) = SafeMathUpgradeable.tryDiv(
totalDividends,
totalDividendsWeight);
uint256 cashPerUnit = currentDividendPerUnit(bIsSandbox);

// 4. calculate the cash dividend per unit for each token, add dividends to
// each address withdrawable balance
Expand All @@ -235,11 +207,19 @@ contract OfferDividendsInstructions is MachineStateManager {
// get total amount of current level of tokens by current token owner
// and get the total dividends
address owner = currentMachineState.tokenList[index].ownerList[tokenOwnerId];


(bIsValid, dividends) = SafeMathUpgradeable.tryMul(
currentMachineState.tokenList[index].tokenBalance[owner],
cashPerUnit);
require(bIsValid, ErrorMsg.By(12));

(bIsValid, dividends) = SafeMathUpgradeable.tryMul(
dividends,
currentMachineState.tokenList[index].dividendWeight
);
require(bIsValid, ErrorMsg.By(12));

// add the dividends to the withdrawable balance of the address
(bIsValid, currentMachineState.withdrawableDividendMap[owner]) = SafeMathUpgradeable.tryAdd(
currentMachineState.withdrawableDividendMap[owner],
Expand Down
18 changes: 18 additions & 0 deletions darc-protocol/contracts/Runtime/Runtime.sol
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,24 @@ contract Runtime is Executable, PaymentCheck{
// if the user pays more than the total payment,
// return the change to withdrawable cash balance
else if (msg.value > totalPayment) {

// check if the current balance of owner is 0,
// and if so, check if the owner is in the withdrawable cash owner list
if (currentMachineState.withdrawableCashMap[program.programOperatorAddress] == 0) {
bool bExist = false;
for (uint256 i = 0; i < currentMachineState.withdrawableCashOwnerList.length; i++) {
if (currentMachineState.withdrawableCashOwnerList[i] == program.programOperatorAddress) {
bExist = true;
break;
}
}

// if the owner is not in the withdrawable cash owner list, add it
if (!bExist) {
currentMachineState.withdrawableCashOwnerList.push(program.programOperatorAddress);
}
}

(bool bIsValid, uint256 paymentReturn) = SafeMathUpgradeable.trySub(msg.value, totalPayment);
require(bIsValid, "The payment return overflow.");
// add the payment return to the withdrawable cash balance
Expand Down
71 changes: 48 additions & 23 deletions darc-protocol/test/operationUnitTest/offer_dividends_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ describe.only("offer_dividends_test", function () {
PLUGIN_ARRAY: [],
UINT256_2DARRAY: [
[BigNumber.from(0), BigNumber.from(1)],
[BigNumber.from(1), BigNumber.from(3)],
[BigNumber.from(1), BigNumber.from(1)],
[BigNumber.from(1), BigNumber.from(3)],
],
ADDRESS_2DARRAY: []
Expand Down Expand Up @@ -96,15 +96,45 @@ describe.only("offer_dividends_test", function () {
PLUGIN_ARRAY: [],
UINT256_2DARRAY: [
// pay 20000
[BigNumber.from(2000000), BigNumber.from(0), BigNumber.from(1)],
[BigNumber.from(200000000000), BigNumber.from(0), BigNumber.from(1)],
],
ADDRESS_2DARRAY: []
}
}],
}, {value: ethers.utils.parseEther("200.0")}
}, {value: ethers.utils.parseEther("1.0")}
);

// get current dividend per unit
const dividendPerUnit = await darc.getCurrentDividendPerUnit();
console.log("dividendPerUnit: ", dividendPerUnit.toString());

console.log("dividendPerUnit: ", dividendPerUnit.toString());


// get total dividends weight of each token owners
let weightArray = [0,0,0];
let addresssArray = [addr1, addr2, addr3];

for (let i = 0; i < (await darc.getNumberOfTokenClasses()).toNumber(); i++) {
const [votingWeight, dividendWeight, tokenInfo, totalSupply] = await darc.getTokenInfo(i);
console.log("votingWeight: ", votingWeight.toString(), " dividendWeight: ", dividendWeight.toString(), " tokenInfo: ", tokenInfo.toString(), " totalSupply: ", totalSupply.toString());

for (let j =0;j<3;j++) {
let balance = await darc.getTokenOwnerBalance(i, addresssArray[j]);
weightArray[j] += balance.toNumber() * dividendWeight.toNumber();
}
}

// print out the weight array
for (let i = 0; i < weightArray.length; i++) {
console.log("weightArray: ", weightArray[i]);
}

// print the dividend weight for each token class
for (let i = 0; i < (await darc.getNumberOfTokenClasses()).toNumber(); i++) {
console.log("token class: ", i, " dividend weight: ")
console.log(await darc.sumDividendWeightByTokenClass(i));
}

// offer dividends
await darc.entrance({
Expand Down Expand Up @@ -157,27 +187,7 @@ describe.only("offer_dividends_test", function () {
console.log("currentCash: ", currentCash.toString(), " by address: " , withdrawableCashOwnerList[i]);
}

// get total dividends weight of each token owners
let weightArray = [0,0,0];
let addresssArray = [addr1, addr2, addr3];

for (let i = 0; i < (await darc.getNumberOfTokenClasses()).toNumber(); i++) {
const [votingWeight, dividendWeight, tokenInfo, totalSupply] = await darc.getTokenInfo(i);
console.log("votingWeight: ", votingWeight.toString(), " dividendWeight: ", dividendWeight.toString(), " tokenInfo: ", tokenInfo.toString(), " totalSupply: ", totalSupply.toString());

for (let j =0;j<3;j++) {
let balance = await darc.getTokenOwnerBalance(i, addresssArray[j]);
weightArray[j] += balance.toNumber() * dividendWeight.toNumber();
}
}

// print out the weight array
for (let i = 0; i < weightArray.length; i++) {
console.log("weightArray: ", weightArray[i]);
}

// print the dividend weight for each token class
//for (let i=0; i)


// list all the balance of the signers
Expand All @@ -188,6 +198,21 @@ describe.only("offer_dividends_test", function () {
console.log("signer: ", signer.address, " balance: ", balance.toString());
}

// list all total supply of each token class
for (let i = 0; i < (await darc.getNumberOfTokenClasses()).toNumber(); i++) {
const result = await darc.getTokenInfo(i);
console.log("token class: ", i, " total supply: ", result[3].toString());
}

// list all withdrawable cash balance
console.log("list all withdrawable cash balance: ")
const ownerList = await darc.getWithdrawableCashOwnerList();
for (let i=0; i< (ownerList).length; i++){
const address = ownerList[i];
const balance = await darc.getWithdrawableCashBalance(address);
console.log("address: ", address, " balance: ", balance.toString());
}

});

});

0 comments on commit c4d58ae

Please sign in to comment.