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

feat: added new functions to get the Stats of QVAULT SC #249

Merged
merged 3 commits into from
Jan 6, 2025
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
2 changes: 1 addition & 1 deletion src/contract_core/contract_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ constexpr struct ContractDescription
{"SWATCH", 123, 10000, sizeof(IPO)},
{"CCF", 127, 10000, sizeof(CCF)}, // proposal in epoch 125, IPO in 126, construction and first use in 127
{"QEARN", 137, 10000, sizeof(QEARN)}, // proposal in epoch 135, IPO in 136, construction in 137 / first donation after END_EPOCH, first round in epoch 138
{"QVAULT", 138, 10000, sizeof(IPO)}, // proposal in epoch 136, IPO in 137, construction and first use in 138
{"QVAULT", 138, 10000, sizeof(QVAULT)}, // proposal in epoch 136, IPO in 137, construction and first use in 138
};

constexpr unsigned int contractCount = sizeof(contractDescriptions) / sizeof(contractDescriptions[0]);
Expand Down
91 changes: 89 additions & 2 deletions src/contracts/QVAULT.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ using namespace QPI;
constexpr uint64 QVAULT_MAX_REINVEST_AMOUNT = 100000000000ULL;
constexpr uint64 QVAULT_QCAP_ASSETNAME = 1346454353;
constexpr uint64 QVAULT_QCAP_MAX_SUPPLY = 21000000;
constexpr uint64 QVAULT_INITIAL_EPOCH = 138;
constexpr uint64 QVAULT_QVAULT_MAX_SUPPLY = 676;
constexpr uint32 QVAULT_MAX_NUMBER_OF_BANNED_ADDRESSES = 16;
constexpr uint32 QVAULT_MAX_EPOCHS = 4096;

struct QVAULT2
{
Expand Down Expand Up @@ -208,8 +211,53 @@ struct QVAULT : public ContractBase
{
};

struct getNumberOfAsset_input
{
uint64 assetName;
id issuer;
uint32 ownershipManagingContractIndex;
};

struct getNumberOfAsset_output
{
sint64 numberOfAssetPossessed;
};

struct getStatsPerEpoch_input
{
uint32 epoch;
};

struct getStatsPerEpoch_output
{
uint64 totalRevenue;
uint64 revenueOfQcapHolders;
uint64 revenueOfOneQcap;
uint64 revenueOfQvaultHolders;
uint64 revenueOfOneQvault;
uint64 revenueOfReinvesting;
uint64 revenueOfDevTeam;
uint64 percentOfReinvested;
uint64 percentOfDistributed;
uint64 percentOfDevTeam;
uint64 percentOfQvaultShareholders;
};

protected:

struct StatsInfo
{
uint64 totalRevenue;
uint64 revenueOfQcapHolders;
uint64 revenueOfOneQcap;
uint64 revenueOfQvaultHolders;
uint64 revenueOfOneQvault;
uint64 revenueOfReinvesting;
uint64 revenueOfDevTeam;
};

array<StatsInfo, QVAULT_MAX_EPOCHS> _allEpochStats;

id QCAP_ISSUER;
id authAddress1, authAddress2, authAddress3, newAuthAddress1, newAuthAddress2, newAuthAddress3;
id reinvestingAddress, newReinvestingAddress1, newReinvestingAddress2, newReinvestingAddress3;
Expand Down Expand Up @@ -559,9 +607,37 @@ struct QVAULT : public ContractBase

_

PUBLIC_FUNCTION(getNumberOfAsset)

output.numberOfAssetPossessed = qpi.numberOfPossessedShares(input.assetName, input.issuer, SELF, SELF, input.ownershipManagingContractIndex, input.ownershipManagingContractIndex);

_

PUBLIC_FUNCTION(getStatsPerEpoch)

if(input.epoch < QVAULT_INITIAL_EPOCH || input.epoch >= QVAULT_MAX_EPOCHS)
{
return ;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make sure that the output contains default values

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

default values for output are all 0.

}

output.totalRevenue = state._allEpochStats.get(input.epoch).totalRevenue;
output.revenueOfQcapHolders = state._allEpochStats.get(input.epoch).revenueOfQcapHolders;
output.revenueOfOneQcap = state._allEpochStats.get(input.epoch).revenueOfOneQcap;
output.revenueOfQvaultHolders = state._allEpochStats.get(input.epoch).revenueOfQvaultHolders;
output.revenueOfOneQvault = state._allEpochStats.get(input.epoch).revenueOfOneQvault;
output.revenueOfDevTeam = state._allEpochStats.get(input.epoch).revenueOfDevTeam;
output.revenueOfReinvesting = state._allEpochStats.get(input.epoch).revenueOfReinvesting;
output.percentOfDistributed = QPI::div(output.revenueOfQcapHolders * 100000ULL, output.totalRevenue);
output.percentOfQvaultShareholders = QPI::div(output.revenueOfQvaultHolders * 100000ULL, output.totalRevenue);
output.percentOfDevTeam = QPI::div(output.revenueOfDevTeam * 100000ULL, output.totalRevenue);
output.percentOfReinvested = QPI::div(output.revenueOfReinvesting * 100000ULL, output.totalRevenue);
_

REGISTER_USER_FUNCTIONS_AND_PROCEDURES

REGISTER_USER_FUNCTION(getData, 1);
REGISTER_USER_FUNCTION(getNumberOfAsset, 2);
REGISTER_USER_FUNCTION(getStatsPerEpoch, 3);

REGISTER_USER_PROCEDURE(submitAuthAddress, 1);
REGISTER_USER_PROCEDURE(changeAuthAddress, 2);
Expand Down Expand Up @@ -604,6 +680,7 @@ struct QVAULT : public ContractBase

struct END_EPOCH_locals
{
StatsInfo statsOfEpoch;
::Entity entity;
AssetPossessionIterator iter;
AssetIssuanceId QCAPId;
Expand Down Expand Up @@ -635,7 +712,7 @@ struct QVAULT : public ContractBase
locals.paymentForReinvest = QVAULT_MAX_REINVEST_AMOUNT;
}

qpi.distributeDividends(div(locals.paymentForShareholders, 676ULL));
qpi.distributeDividends(div(locals.paymentForShareholders, NUMBER_OF_COMPUTORS * 1ULL));
qpi.transfer(state.adminAddress, locals.paymentForDevelopment);
qpi.transfer(state.reinvestingAddress, locals.paymentForReinvest);
qpi.burn(locals.amountOfBurn);
Expand All @@ -647,6 +724,16 @@ struct QVAULT : public ContractBase
locals.circulatedSupply -= qpi.numberOfPossessedShares(QVAULT_QCAP_ASSETNAME, state.QCAP_ISSUER, state.bannedAddress.get(locals._t), state.bannedAddress.get(locals._t), QX_CONTRACT_INDEX, QX_CONTRACT_INDEX);
}

locals.statsOfEpoch.totalRevenue = locals.revenue;
locals.statsOfEpoch.revenueOfQcapHolders = locals.paymentForQCAPHolders;
locals.statsOfEpoch.revenueOfOneQcap = div(locals.paymentForQCAPHolders, locals.circulatedSupply);
locals.statsOfEpoch.revenueOfQvaultHolders = locals.paymentForShareholders;
locals.statsOfEpoch.revenueOfOneQvault = div(locals.paymentForShareholders, NUMBER_OF_COMPUTORS * 1ULL);
locals.statsOfEpoch.revenueOfDevTeam = locals.paymentForDevelopment;
locals.statsOfEpoch.revenueOfReinvesting = locals.paymentForReinvest;

state._allEpochStats.set(qpi.epoch(), locals.statsOfEpoch);

locals.QCAPId.assetName = QVAULT_QCAP_ASSETNAME;
locals.QCAPId.issuer = state.QCAP_ISSUER;

Expand All @@ -672,4 +759,4 @@ struct QVAULT : public ContractBase
}

_
};
};
62 changes: 62 additions & 0 deletions test/contract_qvault.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,26 @@ class QVAULTChecker : public QVAULT
EXPECT_EQ(output.unbannedAddress2, unbannedAddress2);
EXPECT_EQ(output.unbannedAddress3, unbannedAddress3);
}

void getNumberOfAssetChecker(const getNumberOfAsset_output& output)
{
EXPECT_EQ(output.numberOfAssetPossessed, QVAULT_QCAP_MAX_SUPPLY);
}

void getStatsPerEpochChecker(const getStatsPerEpoch_output& output)
{
EXPECT_EQ(output.totalRevenue, _allEpochStats.get(system.epoch).totalRevenue);
EXPECT_EQ(output.revenueOfQcapHolders, _allEpochStats.get(system.epoch).revenueOfQcapHolders);
EXPECT_EQ(output.revenueOfQvaultHolders, _allEpochStats.get(system.epoch).revenueOfQvaultHolders);
EXPECT_EQ(output.revenueOfOneQcap, _allEpochStats.get(system.epoch).revenueOfOneQcap);
EXPECT_EQ(output.revenueOfOneQvault, _allEpochStats.get(system.epoch).revenueOfOneQvault);
EXPECT_EQ(output.revenueOfDevTeam, _allEpochStats.get(system.epoch).revenueOfDevTeam);
EXPECT_EQ(output.revenueOfReinvesting, _allEpochStats.get(system.epoch).revenueOfReinvesting);
EXPECT_EQ(output.percentOfDistributed, QPI::div(_allEpochStats.get(system.epoch).revenueOfQcapHolders * 100000ULL, _allEpochStats.get(system.epoch).totalRevenue));
EXPECT_EQ(output.percentOfQvaultShareholders, QPI::div(_allEpochStats.get(system.epoch).revenueOfQvaultHolders * 100000ULL, _allEpochStats.get(system.epoch).totalRevenue));
EXPECT_EQ(output.percentOfReinvested, QPI::div(_allEpochStats.get(system.epoch).revenueOfReinvesting * 100000ULL, _allEpochStats.get(system.epoch).totalRevenue));
EXPECT_EQ(output.percentOfDevTeam, QPI::div(_allEpochStats.get(system.epoch).revenueOfDevTeam * 100000ULL, _allEpochStats.get(system.epoch).totalRevenue));
}
};

class ContractTestingQvault : protected ContractTesting
Expand Down Expand Up @@ -289,6 +309,30 @@ class ContractTestingQvault : protected ContractTesting
return output;
}

QVAULT::getNumberOfAsset_output getNumberOfAsset(uint64 assetName, id issuer, uint32 ownershipManagingContractIndex) const
{
QVAULT::getNumberOfAsset_input input;
QVAULT::getNumberOfAsset_output output;

input.assetName = assetName;
input.issuer = issuer;
input.ownershipManagingContractIndex = ownershipManagingContractIndex;

callFunction(QVAULT_CONTRACT_INDEX, 2, input, output);
return output;
}

QVAULT::getStatsPerEpoch_output getStatsPerEpoch(uint16 epoch) const
{
QVAULT::getStatsPerEpoch_input input;
QVAULT::getStatsPerEpoch_output output;

input.epoch = epoch;

callFunction(QVAULT_CONTRACT_INDEX, 3, input, output);
return output;
}

void submitAuthAddress(const id& authAddress, const id& newAuthAddress)
{
QVAULT::submitAuthAddress_input input;
Expand Down Expand Up @@ -500,6 +544,8 @@ TEST(ContractQvault, END_EPOCH)
uint64 revenue = random(QVAULT_MIN_REVENUE, QVAULT_MAX_REVENUE);
increaseEnergy(QVAULT_CONTRACT_ID, revenue);
qvault.endEpoch();
auto output = qvault.getStatsPerEpoch(system.epoch);
qvault.getState()->getStatsPerEpochChecker(output);
qvault.getState()->endEpochChecker(revenue, QCAPHolders);
}

Expand Down Expand Up @@ -877,4 +923,20 @@ TEST(ContractQvault, getData)

output = qvault.getData();
qvault.getState()->getDataChecker(output);
}

TEST(ContractQvault, getNumberOfAsset)
{
ContractTestingQvault qvault;

id issuer = QVAULT_QCAP_ISSUER;
uint64 assetName = assetNameFromString("QCAP");
sint64 numberOfShares = QVAULT_QCAP_MAX_SUPPLY;

increaseEnergy(issuer, QVAULT_ISSUE_ASSET_FEE + QVAULT_TOKEN_TRANSFER_FEE);
EXPECT_EQ(qvault.issueAsset(issuer, assetName, numberOfShares, 0, 0), numberOfShares);
EXPECT_EQ(qvault.TransferShareOwnershipAndPossession(issuer, assetName, numberOfShares, QVAULT_CONTRACT_ID), numberOfShares);

auto output = qvault.getNumberOfAsset(assetName, issuer, 1);
qvault.getState()->getNumberOfAssetChecker(output);
}
Loading