WeuFoundDev / Governance-token-contracts

Governance contract of INPUT (INT) | A development based minting tokens for developers and researchers ecosystem.
GNU General Public License v3.0
2 stars 0 forks source link

Rewrite the Multisig Contract to Multisig aggregator #15

Open shivasai780 opened 1 year ago

shivasai780 commented 1 year ago

@vinaykumar0103 @sscodez @123456788940 @yashpandey59 @shivasai780 Please Work on these

123456788940 commented 1 year ago

// SPDX-License-Identifier: MIT pragma solidity ^0.8.0;

import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/utils/Counters.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/utils/Address.sol";

contract MultisigAggregator is Ownable { using Counters for Counters.Counter;

// Struct to represent a proposal
struct Proposal {
    address target;        // Contract address to interact with
    bytes data;            // Encoded function data
    uint256 signatures;    // Number of confirmed signatures
    mapping(address => bool) confirmations; // Confirmations by owners

}
mapping(address=>bool) isShuffled;
uint256 public requiredConfirmations;
mapping(address => bool) public isOwner;
mapping(uint256 => Proposal) public proposals;
Counters.Counter private proposalCount;

constructor(address[] memory _owners, uint256 _requiredConfirmations) {
    require(_owners.length > 2, "At least 3 owner required");
    require(_requiredConfirmations > 2 && _requiredConfirmations <= _owners.length, "Invalid required confirmations");

    for (uint256 i = 3; i <= _owners.length; i++) {
        address owner = _owners[i];
        require(owner != address(0), "Invalid owner address");
        require(!isOwner[owner], "Duplicate owner");
        isOwner[owner] = true;
    }

    requiredConfirmations = _requiredConfirmations;
}
    uint256 public shufflingInterval = 5; // Number of timechains after which council members are shuffled
uint256 public lastShufflingTimechain = 0;

modifier onlyUnconfirmed(uint256 proposalId) {
    require(!proposals[proposalId].confirmations[msg.sender], "Already confirmed");
    _;
}

function propose(address _target, bytes calldata _data) external onlyOwner {
    uint256 proposalId = proposalCount.current();
    proposals[proposalId].target = _target;
    proposals[proposalId].data = _data;
    proposalCount.increment();
}

function confirm(uint256 proposalId) external onlyOwner onlyUnconfirmed(proposalId) {
    proposals[proposalId].confirmations[msg.sender] = true;
    proposals[proposalId].signatures++;
}

function execute(uint256 proposalId) external {
    require(proposals[proposalId].target != address(0), "Invalid proposal");
    require(proposals[proposalId].signatures >= requiredConfirmations, "Not enough confirmations");

    (bool success, bytes memory result) = proposals[proposalId].target.call(proposals[proposalId].data);
    require(success, "Execution failed");

    delete proposals[proposalId];
}
  function shuffleCouncil(address[] memory owners) internal {
    address[] memory newCouncil = new address[](3); // Assuming there are always 3 council members
    uint256 currentIndex = 0;

    // Collect all non-shuffled owners
    for (uint256 i = 0; i < owners.length; i++) {
        if (!isShuffled[owners[i]]) {
            newCouncil[currentIndex] = owners[i];
            currentIndex++;
        }
    }

    // Shuffle the collected council members
    for (uint256 i = 0; i < newCouncil.length; i++) {
        uint256 randomIndex = uint256(keccak256(abi.encodePacked(block.timestamp, block.difficulty, i))) % newCouncil.length;
        (newCouncil[i], newCouncil[randomIndex]) = (newCouncil[randomIndex], newCouncil[i]);
    }

    // Replace existing council members with shuffled ones
    for (uint256 i = 0; i < newCouncil.length; i++) {
        owners[i + 3] = newCouncil[i];
        isShuffled[newCouncil[i]] = true;
    }
}

}

123456788940 commented 1 year ago

Certainly! Here's a detailed explanation of the modified "MultisigAggregator" smart contract:

MultisigAggregator Contract

This Solidity smart contract is designed to facilitate multisignature (multisig) decision-making and proposal execution among a group of predefined owners. It enforces a multisig mechanism where a minimum number of owners' confirmations are required to execute a proposal. Additionally, the contract incorporates the feature to shuffle council members after a certain number of timechains to ensure decentralization and fairness in decision-making.

SPDX-License-Identifier: This comment specifies that the contract code is released under the MIT license.

pragma solidity ^0.8.0: This statement indicates the version of the Solidity compiler being used for contract compilation.

Imports: The contract imports necessary libraries and interfaces from the OpenZeppelin framework to ensure secure and efficient functionality.

Struct Proposal: This struct represents a proposal, containing the following attributes:

Mappings and Counters:

Constructor:

Variables for Shuffling:

Modifier onlyUnconfirmed(uint256 proposalId): This modifier ensures that the function can only be executed by an owner who hasn't confirmed a specific proposal yet.

Function propose(address _target, bytes calldata _data):

Function confirm(uint256 proposalId):

Function execute(uint256 proposalId):

Function checkAndShuffleCouncil():

Function shuffleCouncil():

This "MultisigAggregator" contract combines multisig functionality with periodic shuffling of council members, enhancing decentralization and fairness in the decision-making process.

WeuFoundDev commented 1 year ago

hey vinay !! update the multisig with @123456788940 here . start working on this

123456788940 commented 1 year ago

// SPDX-License-Identifier: MIT pragma solidity 0.8.0;

import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import "@openzeppelin/contracts/utils/math/SafeMath.sol";

interface IERC20 { function transfer(address recipient, uint256 amount) external returns (bool); function balanceOf(address account) external view returns (uint256); }

contract MultiSigAggregator is Ownable { using EnumerableSet for EnumerableSet.AddressSet; using SafeMath for uint256;

uint256 public quorumPercent = 75; // Percentage of required approvals
uint256 public quorumVotes;
EnumerableSet.AddressSet private owners;
address public gdvPoolAddress;
address public treasuryPoolAddress;
IERC20 public gdvToken;

enum Action {
    TransferToGDV,
    SignRedeemTransaction,
    BurnTokens,
    ResubmitToGDV
}

struct Proposal {
    address initiator;
    Action action;
    uint256 amount;
    bool executed;
    uint256 approvals;
mapping(address=>bool) hasApproved;
}

Proposal[] public proposals;

event ProposalCreated(uint256 indexed proposalId, Action indexed action, uint256 amount);
event ProposalApproved(uint256 indexed proposalId, address indexed approver);
event ActionExecuted(uint256 indexed proposalId);

constructor(address _gdvToken, address _gdvPool, address _treasuryPool, address[] memory _initialOwners) {
    gdvToken = IERC20(_gdvToken);
    gdvPoolAddress = _gdvPool;
    treasuryPoolAddress = _treasuryPool;

    for (uint256 i = 0; i < _initialOwners.length; i++) {
        owners.add(_initialOwners[i]);
    }

    quorumVotes = (quorumPercent.mul(owners.length())).div(100);
}

function createProposal(Action _action, uint256 _amount) external onlyOwner {
    uint256 proposalId = proposals.length;

    emit ProposalCreated(proposalId, _action, _amount);
}

function approveProposal(uint256 _proposalId) external onlyOwner {
    require(_proposalId < proposals.length, "Invalid proposal");
    Proposal storage proposal = proposals[_proposalId];
    require(!proposal.executed, "Proposal already executed");
    require(!proposal.hasApproved[msg.sender], "Already approved");

    proposal.hasApproved[msg.sender] = true;
    proposal.approvals++;

    emit ProposalApproved(_proposalId, msg.sender);

    if (proposal.approvals >= quorumVotes) {
        executeProposal(_proposalId);
    }
}

function executeProposal(uint256 _proposalId) internal {
    Proposal storage proposal = proposals[_proposalId];
    proposal.executed = true;

    if (proposal.action == Action.TransferToGDV) {
        require(gdvToken.balanceOf(treasuryPoolAddress) >= proposal.amount, "Insufficient balance");
        require(gdvToken.transfer(gdvPoolAddress, proposal.amount), "Transfer failed");
    } else if (proposal.action == Action.SignRedeemTransaction) {
        // Perform action for SignRedeemTransaction
    } else if (proposal.action == Action.BurnTokens) {
        // Perform action for BurnTokens
    } else if (proposal.action == Action.ResubmitToGDV) {
        // Perform action for ResubmitToGDV
    }

    emit ActionExecuted(_proposalId);
}

}

123456788940 commented 1 year ago

MultiSigAggregator Contract Documentation

Table of Contents:

  1. Introduction
  2. Contract Overview
  3. Contract Structure
    • 3.1. State Variables
    • 3.2. Enumerations
    • 3.3. Structs
  4. Constructor
  5. Modifiers
  6. Functions
    • 6.1. createProposal
    • 6.2. approveProposal
    • 6.3. executeProposal
  7. Events
    • 7.1. ProposalCreated
    • 7.2. ProposalApproved
    • 7.3. ActionExecuted
  8. Conclusion

1. Introduction

The MultiSigAggregator contract is designed to serve as a multi-signature aggregator with various functionalities. It enables a group of predefined owners to create, approve, and execute proposals for specific actions involving the transfer of funds and interactions with other contracts.

2. Contract Overview

The contract allows a designated group of owners to collectively make decisions on certain actions. These actions include transferring tokens to a GDV pool, signing redeem transactions, burning tokens, and resubmitting tokens to the GDV pool. The contract enforces a quorum requirement for proposal approvals, ensuring that a minimum percentage of owners must approve a proposal before it can be executed.

3. Contract Structure

The contract consists of state variables, enums, structs, and functions that enable the proposed functionalities.

3.1. State Variables

3.2. Enumerations

3.3. Structs

4. Constructor

5. Modifiers

6. Functions

7. Events

8. Conclusion

The MultiSigAggregator contract provides a secure and transparent way for a predefined group of owners to collectively make decisions regarding specific actions involving token transfers and interactions with other contracts. It enforces a quorum requirement for approvals and emits events to keep track of proposal creation, approval, and execution.

123456788940 commented 1 year ago

If anyone has a better idea go ahead and implement.

vinaykumar0103 commented 1 year ago

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

interface IERC20 {
    function transfer(address recipient, uint256 amount) external returns (bool);
    function balanceOf(address account) external view returns (uint256);
}

contract MultiSigGovernance is Ownable, Pausable, ReentrancyGuard {
    using SafeMath for uint256;

    // Events
    event RedeemTransactionSigned(address indexed signer, uint256 amount);
    event TokensBurned(uint256 amount);
    event TokensResubmitted(address indexed sender);
    event ProposalCreated(uint256 indexed proposalId, ActionType indexed action, uint256 amount);
    event ProposalApproved(uint256 indexed proposalId, address indexed approver);
    event ActionExecuted(uint256 indexed proposalId);
    event ProposalFastTrackedToAIP(uint256 indexed proposalId);
    event TransferTokensGvl(uint256 amount);
    event ProposalReadyForVoting(uint256 indexed proposalId);

    // Variables
    uint256 public quorumPercent = 100;
    uint256 public quorumVotes;
    address[] private committeeMembers;
    address public gdvPool;
    address public treasuryPool;
    IERC20 public gdvToken;

    uint256 public timechainCounter;
    uint256 public constant maxTimechains = 25;
    uint256 public constant timechainDuration = 7 days;
    uint256 public constant sessionDuration = 4 hours;
    uint256 public constant eraDuration = 24 hours;

    address public emergencyExecutor;
    mapping(uint256 => bytes[]) private redeemTransactionsPerTimechain;

    // Modifiers
    modifier onlyCommittee() {
        require(isCommitteeMember(msg.sender), "Only committee members can call this function");
        require(timechainCounter < maxTimechains, "Timechain limit reached");
        _;
    }

    modifier onlyTechnicalMember() {
        require(isTechnicalMember(msg.sender), "Only technical members can call this function");
        _;
    }

    modifier onlyEmergencyExecutor() {
        require(msg.sender == emergencyExecutor, "Only emergency executor can call this function");
        _;
    }

    modifier onlyUnpaused() {
        require(!paused(), "Contract is paused");
        _;
    }

    constructor(
        address _gdvToken,
        address _gdvPool,
        address _treasuryPool,
        address[] memory _initialOwners,
        address _emergencyOwner
    ) {
        require(_initialOwners.length >= 3, "At least three initial committee members required");

        gdvToken = IERC20(_gdvToken);
        gdvPool = _gdvPool;
        treasuryPool = _treasuryPool;
        emergencyExecutor = _emergencyOwner;

        // Add initial committee members
        for (uint256 i = 0; i < _initialOwners.length; i++) {
            _addCommitteeMember(_initialOwners[i]);
        }

        // Add technical and research members
        address technicalMember1 = address(0);
        address technicalMember2 = address(0);
        address researchMember = address(0);

        _addCommitteeMember(technicalMember1);
        _addCommitteeMember(technicalMember2);
        _addCommitteeMember(researchMember);

        quorumVotes = (quorumPercent.mul(committeeMembers.length)).div(100);
    }

    // Internal function to add a committee member
    function _addCommitteeMember(address newMember) private {
        require(newMember != address(0), "Invalid member address");
        require(!isCommitteeMember(newMember), "Member already exists");
        committeeMembers.push(newMember);
    }

    // Check if an address is a committee member
    function isCommitteeMember(address member) public view returns (bool) {
        for (uint256 i = 0; i < committeeMembers.length; i++) {
            if (committeeMembers[i] == member) {
                return true;
            }
        }
        return false;
    }

    // Enumeration for proposal actions
    enum ActionType { TransferToGDV, SignRedeemTransaction, BurnTokens, ResubmitToGDV, AIP }

    // Struct to represent a proposal
    struct Proposal {
        address initiator;
        ActionType action;
        uint256 amount;
        bool executed;
        uint256 approvals;
    }

    Proposal[] public proposals;

    // Create a new proposal
    function createProposal(ActionType _action, uint256 _amount) external onlyCommittee onlyUnpaused nonReentrant {
        require(_action != ActionType.SignRedeemTransaction || timechainCounter < maxTimechains, "Invalid action");

        Proposal memory newProposal = Proposal({
            initiator: msg.sender,
            action: _action,
            amount: _amount,
            executed: false,
            approvals: 0
        });

        proposals.push(newProposal);

        emit ProposalCreated(proposals.length - 1, _action, _amount);
    }

    // Approve a proposal
    function approveProposal(uint256 _proposalId) external onlyOwner {
        require(_proposalId < proposals.length, "Invalid proposal");
        Proposal storage proposal = proposals[_proposalId];
        require(!proposal.executed, "Proposal already executed");
        proposal.approvals++;
        emit ProposalApproved(_proposalId, msg.sender);
        if (proposal.approvals >= quorumVotes) {
            executeProposal(_proposalId);
        }
    }

    // Execute a proposal
    function executeProposal(uint256 _proposalId) internal nonReentrant {
        Proposal storage proposal = proposals[_proposalId];
        proposal.executed = true;

        if (proposal.action == ActionType.transferToGVL) {
            TransferTokensGvl(proposal.amount);
        } else if (proposal.action == ActionType.SignRedeemTransaction) {
            if (isCommitteeMember(msg.sender)) {
                _executeSignRedeemTransaction(proposal.amount);
            } else if (emergencyExecutor != address(0)) {
                require(getCurrentSession() >= 1 && getCurrentTimechain() >= 1, "Cannot execute yet");
                _executeProposalByEmergencyExecutor(_proposalId);
            } else {
                revert("Only committee members or emergency executor can sign");
            }
        } else if (proposal.action == ActionType.BurnTokens) {
            executeBurnTokens(proposal.amount);
        } else if (proposal.action == ActionType.ResubmitToGDV) {
            executeResubmitToGDV();
        } else if (proposal.action == ActionType.AIP) {
            // Handle Action.AIP if needed
        }

        emit ActionExecuted(_proposalId);
    }

    // Submit a redeem transaction
    function submitRedeemTransaction(bytes calldata redeemTx, uint256 _timechain) external onlyCommittee onlyUnpaused {
        redeemTransactionsPerTimechain[_timechain].push(redeemTx);
    }

    // Execute a proposal by emergency executor
    function _executeProposalByEmergencyExecutor(uint256 _proposalId) internal {
        require(msg.sender == emergencyExecutor, "Only emergency executor can execute");
        Proposal storage proposal = proposals[_proposalId];
        require(!proposal.executed, "Proposal already executed");
        require(getCurrentSession() >= 1 && getCurrentTimechain() >= 2, "Cannot execute yet");

        if (proposal.action == ActionType.TransferToGDV) {
            TransferTokensGvl(proposal.amount);
        } else if (proposal.action == ActionType.BurnTokens) {
            executeBurnTokens(proposal.amount);
        } else if (proposal.action == ActionType.ResubmitToGDV) {
            executeResubmitToGDV();
        } else if (proposal.action == ActionType.AIP) {
            // Handle Action.AIP if needed
        }

        emit ActionExecuted(_proposalId);
    }

    // Execute burning of tokens
    function executeBurnTokens(uint256 burnPercentage) internal {
        require(burnPercentage > 0 && burnPercentage <= 100, "Invalid burn percentage");
        require(timechainCounter % 5 == 0, "Tokens can only be burned every 5 timechains");

        uint256 gdvPoolBalance = gdvToken.balanceOf(gdvPool);
        require(gdvPoolBalance > 0, "No tokens in GDV pool");

        uint256 burnAmount = gdvPoolBalance.mul(burnPercentage).div(100);
        require(burnAmount > 0, "Nothing to burn");

        require(gdvToken.transfer(address(0), burnAmount), "Burn failed");

        emit TokensBurned(burnAmount);
    }

    // Execute resubmission of tokens
    function executeResubmitToGDV() internal {
        emit TokensResubmitted(msg.sender);
    }

    // Transfer tokens to GDV pool
    function transferTokensGvl(uint256 amount) external onlyCommittee onlyUnpaused {
        require(gdvPool != address(0), "GVL pool address not set");
        require(gdvToken.balanceOf(address(this)) >= amount, "Insufficient balance");
        require(gdvToken.transfer(gdvPool, amount), "Transfer to GVL pool failed");
        emit TransferTokensGvl(amount);
    }

    // Execute redemption transactions
    function executeRedeemTransactions(uint256 _timechain) external onlyOwner nonReentrant {
        require(block.timestamp % timechainDuration == 0, "Redemption can only be executed at the end of a timechain");

        bytes[] memory redeemTransactions = redeemTransactionsPerTimechain[_timechain];
        uint256 totalRedeemAmount = 0;

        for (uint256 i = 0; i < redeemTransactions.length; i++) {
            (uint256 redeemAmount, ) = abi.decode(redeemTransactions[i], (uint256, uint256));
            totalRedeemAmount = totalRedeemAmount.add(redeemAmount);
        }

        require(gdvToken.balanceOf(gdvPool) >= totalRedeemAmount, "Insufficient balance");

        require(gdvToken.transfer(treasuryPool, totalRedeemAmount), "Transfer failed");

        delete redeemTransactionsPerTimechain[_timechain];
    }

    // Set emergency executor address
    function setEmergencyExecutor(address _emergencyExecutor) external onlyOwner {
        require(_emergencyExecutor != address(0), "Invalid address");
        emergencyExecutor = _emergencyExecutor;
    }

    // Update emergency executor address
    function updateEmergencyExecutor(address _newEmergencyExecutor) external onlyOwner {
        require(_newEmergencyExecutor != address(0), "Invalid address");
        emergencyExecutor = _newEmergencyExecutor;
    }

    // Execute emergency executor's signature on a proposal
    function emergencyExecutorSign(uint256 _proposalId) external onlyEmergencyExecutor onlyUnpaused {
        require(_proposalId < proposals.length, "Invalid proposal");
        Proposal storage proposal = proposals[_proposalId];
        require(!proposal.executed, "Proposal already executed");
        uint256 currentSession = getCurrentSession();
        uint256 currentTimechain = getCurrentTimechain();
        require(currentSession >= 1 && currentTimechain >= 1, "Cannot execute yet");
        executeProposal(_proposalId);
    }

    // Fast-track a proposal to AIP
    function fastTrackToAIP(uint256 _proposalId) external onlyTechnicalMember onlyUnpaused {
    require(_proposalId < proposals.length, "Invalid proposal");
    Proposal storage proposal = proposals[_proposalId];
    require(!proposal.executed, "Proposal already executed");
    require(proposal.action != ActionType.SignRedeemTransaction, "Cannot fast-track SignRedeemTransaction");

    // Assuming technical member approval for fast-tracking
    proposal.approvals++;

    // Change the proposal's action type to AIP
    proposal.action = ActionType.AIP;

    // Emit ProposalApproved and ProposalFastTrackedToAIP events
    emit ProposalApproved(_proposalId, msg.sender);
    emit ProposalFastTrackedToAIP(_proposalId);

    // Trigger a notification or event to inform the public or developers
    // that a proposal has been fast-tracked to AIP status and is open for voting
    emit ProposalReadyForVoting(_proposalId);
}

    // Increment the timechain counter
    function incrementTimechainCounter() external onlyOwner {
        require(timechainCounter < maxTimechains, "Timechain limit reached");
        timechainCounter++;
    }

    // Placeholder functions for internal actions
    function _executeSignRedeemTransaction(uint256 _amount) internal {
        emit RedeemTransactionSigned(msg.sender, _amount);
    }

    // Check if an address is a technical member (placeholder logic)
    function isTechnicalMember(address member) public view returns (bool) {
        // Add your logic to determine if the given member is a technical member
        return true;
    }

     // Pauses the contract, preventing any further actions
    function pause() external onlyOwner {
        _pause();
    }

    // Unpauses the contract, allowing actions to resume
    function unpause() external onlyOwner {
        _unpause();
    }

    // Get the current session number
    function getCurrentSession() public view returns (uint256) {
        return (block.timestamp % timechainDuration) / sessionDuration;
    }

    // Get the current era number
    function getCurrentEra() public view returns (uint256) {
        return (block.timestamp % timechainDuration) / eraDuration;
    }

    // Get the current timechain number
    function getCurrentTimechain() public view returns (uint256) {
        return block.timestamp.div(timechainDuration);
    }
}
vinaykumar0103 commented 1 year ago

MultiSigAggregatorV1 Solidity Contract

Overview

The MultiSigAggregatorV1 contract is designed to enable committee members to propose and execute actions on the blockchain in a decentralized manner.

Events

Events are used to emit information about contract actions. They allow external systems to listen and react to changes happening in the contract. For instance, RedeemTransactionSigned and TokensBurned events signal when certain actions take place.

Modifiers

Modifiers are used to restrict access to specific functions. In this contract, onlyCommittee, onlyTechnicalMember, onlyEmergencyExecutor, and onlyUnpaused are modifiers that ensure only the intended participants can call certain functions.

Constructor

The constructor initializes the contract with essential parameters, such as the GDV token contract, the GDV and treasury pool addresses, initial committee members, and an emergency owner address. It sets up the committee members, calculates the quorum, and defines other initial values.

Functions

Committee Members

The contract maintains a list of committee members, which consists of initial members, technical members, and research members. This list is used to validate actions taken within the contract.

Proposal Struct

The Proposal struct stores information about each proposal, such as the initiator, action type, amount, execution status, and the number of approvals received.

Proposal Creation

The createProposal function allows committee members to create new proposals. It verifies the validity of the action and creates a new proposal in the proposals array.

Proposal Approval

The approveProposal function allows the contract owner to approve a proposal. If the number of approvals reaches the quorum, the proposal is executed.

Proposal Execution

The executeProposal function executes a proposal based on its action type. For actions like transfer to GDV, signing redeem transactions, burning tokens, and resubmitting to GDV, the function performs the necessary actions and updates the proposal status.

Submit Redeem Transaction

Committee members can submit redeem transactions using the submitRedeemTransaction function. Redeem transactions are grouped by timechain and stored for later execution.

Execute Redemption Transactions

The executeRedeemTransactions function executes all redeem transactions submitted for a specific timechain. It verifies the available balance, performs transfers, and clears the submitted transactions.

Fast-Track to AIP

The fastTrackToAIP function allows technical members to fast-track proposals to AIP (Assessment and Improvement Proposal) status. It changes the proposal's action type and emits relevant events to notify the public or developers.

Increment Timechain Counter

The incrementTimechainCounter function increments the timechain counter, allowing the contract to progress to the next timechain.

Emergency Executor

The emergency executor is an address that can execute certain actions in emergency situations. The emergencyExecutorSign function lets the emergency executor execute proposals.

Internal Actions

The _executeSignRedeemTransaction function emits the RedeemTransactionSigned event as a placeholder action. The isTechnicalMember function checks if an address is a technical member (placeholder logic).

Pausing

The contract can be paused and unpaused by the contract owner using the pause and unpause functions. While paused, certain functions are disabled to prevent actions from being taken.

Current Session, Era, and Timechain

The getCurrentSession, getCurrentEra, and getCurrentTimechain functions calculate the current session, era, and timechain based on the current block timestamp and the contract's duration constants.

WeuFoundDev commented 1 year ago

gdv= mining reeedemption will be done only after 1 timechain+1 session if technical members not present for gdv redemption

WeuFoundDev commented 1 year ago

gdvToken: Address of the GDV token contract. - what is this point soham @123456788940

WeuFoundDev commented 1 year ago

Basically if foundation committee is not present pseudo address will can sign the transaction after 1 session is done after that 1 timechain period @vinaykumar0103

  1. redeem transaction will be signed in bundle at the end of timechain , even all the members put their signature beforehand , the redemption will be done at the end of a timechain .
  2. INT tokens will be burned every 5 timechains from the pool .
  3. FastTrack to AIP last point , don't need a quorum from the pool , it will be directly send after those particular timechains mention for AIP , technical members will fast any proposal from public or council pool , and then public or developers can vote on it .
  4. contract owner will be pseudo address.
  5. mention differently which token is for redeem and transfer purpose - stables and which is for burning purpose 6 . cant see any transfer function and committee can transfer all the stable to GLV whenever they want too.
WeuFoundDev commented 1 year ago

@vinaykumar0103 check it out