ROLL NO: [Link].
U4CSE23254
NAME: VimalHariHar S K
pragma solidity ^0.8.0;
contract quantumnexusvault {
address private supremecontroller;
address[] private memberregistry;
uint private vaultreserve;
enum motionstate { pending, executed, dismissed }
struct motion {
uint motionid;
uint requestamount;
motionstate state;
uint yesvotes;
uint novotes;
mapping(address => bool) ballotrecord;
}
motion[] private motionlog;
uint private totalexecuted = 0;
uint private totalpending = 0;
uint private totaldismissed = 0;
bool private isvaultsetup = false;
modifier onlycontroller() {
require([Link] == supremecontroller, "access restricted to supreme
controller!");
_;
}
function ismember(address candidate) private view returns (bool) {
for (uint i = 0; i < [Link]; i++) {
if (memberregistry[i] == candidate) {
return true;
}
}
return false;
}
modifier onlymember() {
require(ismember([Link]), "only members may access this function!");
_;
}
modifier motionexists(uint motionindex) {
require(motionindex < [Link], "motion not found!");
_;
}
modifier nonzeroamount(uint amount) {
require(amount > 0, "requested amount must be greater than zero!");
_;
}
modifier pendingonly(uint motionindex) {
require(motionlog[motionindex].state == [Link], "only pending
motions can be voted!");
_;
}
modifier vaultnotinitialized() {
require(isvaultsetup == false, "vault already initialized!");
_;
}
event vaultconfigured(address[] members, uint startingbalance);
event motionsubmitted(uint id, address initiator, uint amount);
event motionapprovedvote(uint id, address voter);
event motionrejectedvote(uint id, address voter);
event motionexecuted(uint id, uint amount);
event motiondismissed(uint id, uint amount);
constructor() {
supremecontroller = [Link];
}
function configurevault(address[] memory participants, uint initialfunds)
public
vaultnotinitialized
nonzeroamount(initialfunds)
onlycontroller
{
require([Link] > 0, "at least one member required!");
for (uint i = 0; i < [Link]; i++) {
require(participants[i] != supremecontroller, "controller cannot be a member!");
for (uint j = 0; j < i; j++) {
require(participants[i] != participants[j], "duplicate members not allowed!");
}
}
memberregistry = participants;
vaultreserve = initialfunds;
isvaultsetup = true;
emit vaultconfigured(participants, initialfunds);
}
function submitmotion(uint amount) public onlymember nonzeroamount(amount) {
[Link]();
uint idx = [Link] - 1;
motion storage m = motionlog[idx];
[Link] = idx;
[Link] = amount;
[Link] = [Link];
[Link] = 1;
[Link] = 0;
[Link][[Link]] = true;
totalpending++;
emit motionsubmitted(idx, [Link], amount);
}
function approvemotion(uint motionindex)
public
onlymember
motionexists(motionindex)
pendingonly(motionindex)
{
motion storage m = motionlog[motionindex];
require(![Link][[Link]], "vote already cast!");
[Link] += 1;
[Link][[Link]] = true;
emit motionapprovedvote(motionindex, [Link]);
if ([Link] > vaultreserve) {
[Link] = [Link];
totaldismissed++;
totalpending--;
emit motiondismissed(motionindex, [Link]);
return;
}
if ([Link] * 100 >= [Link] * 70) {
[Link] = [Link];
totalexecuted++;
totalpending--;
vaultreserve -= [Link];
emit motionexecuted(motionindex, [Link]);
}
}
function rejectmotion(uint motionindex)
public
onlymember
motionexists(motionindex)
pendingonly(motionindex)
{
motion storage m = motionlog[motionindex];
require(![Link][[Link]], "vote already cast!");
[Link] += 1;
[Link][[Link]] = true;
emit motionrejectedvote(motionindex, [Link]);
if ([Link] * 100 > [Link] * 30 || [Link] > vaultreserve)
{
[Link] = [Link];
totaldismissed++;
totalpending--;
emit motiondismissed(motionindex, [Link]);
}
}
function getvaultbalance() public view onlymember returns (uint) {
return vaultreserve;
}
function getmotionstatus(uint motionindex)
public
view
onlymember
motionexists(motionindex)
returns (uint requestamount, string memory statuslabel)
{
motion storage m = motionlog[motionindex];
requestamount = [Link];
if ([Link] == [Link]) {
statuslabel = "pending";
} else if ([Link] == [Link]) {
statuslabel = "executed";
} else {
statuslabel = "dismissed";
}
}
function getmotionsummary()
public
view
onlymember
returns (uint executedcount, uint pendingcount, uint dismissedcount)
{
executedcount = totalexecuted;
pendingcount = totalpending;
dismissedcount = totaldismissed;
}
function getmembercount() public view returns (uint) {
return [Link];
}
function gettotalmotions() public view returns (uint) {
return [Link];
}
}
SAMPLE I/O:
//Input Output
Input:
setMyWallet :
[0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2,0x4B20993Bc481177ec7E8f571c
eCaE8A9e22C02db,0x78731D3Ca6b7E34aC0F824c42a7cC18A495cabaB],
1000
Input:
proposeExpenditure - 200 // by 0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2
Input:
approveProposal - 0 // by 0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db
Input:
approveProposal - 0 // by 0x78731D3Ca6b7E34aC0F824c42a7cC18A495cabaB
Output:
viewProposal - 0
0: uint256: value 200
1: string: statusText disbursed
currentBalance:
0: uint256: 800
proposalSummary:
0: uint256: disbursedCount 1
1: uint256: pendingCount 0
2: uint256: rejectedCount 0
---
// Another case
Input:
proposeExpenditure - 300 // by 0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db
Input:
rejectProposal - 1 // by 0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2
Input:
rejectProposal - 1 // by 0x78731D3Ca6b7E34aC0F824c42a7cC18A495cabaB
Output:
viewProposal - 1
0: uint256: value 300
1: string: statusText rejected
currentBalance:
0: uint256: 800
proposalSummary:
0: uint256: disbursedCount 1
1: uint256: pendingCount 0
2: uint256: rejectedCount 1
*/