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

Write a functionality in burning contract that the dev can burn and claim the usd after end of every timechain #16

Closed shivasai780 closed 1 year ago

shivasai780 commented 1 year ago

@shivasai780 @sscodez @123456788940 @vinaykumar0103 @sscodez @yashpandey59

vinaykumar0103 commented 1 year ago


  // SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./Iint.sol";

contract TimechainProtocol is ReentrancyGuard {
    // Define the structure for the protocol's Burning pool
    struct BurningPool {
        uint256 totalInputs;
        uint256 timeChainsLeft;
        mapping(uint => mapping(uint => uint)) slashingPercentage; // slashingpercent[number of investment][Amount]=slashpercent
        mapping(uint => uint) amountStaked;
        uint256 noOfinvestments;
        address usdUsed;
        uint256 startingBlock;
        uint256 totalslashedAmount;
    }

    // Mapping to store the protocol's Burning pool data
    mapping(address => BurningPool) public BurningPools;

    // GLIPs vault to hold the slashed INT
    mapping(address => uint256) public glipsVaultAmount;

    address public stableCoin1;
    address public stableCoin2;
    address public stableCoin3;
    address public stableCoin4;
    address public glipsVault;
    Iint public intToken;
    address public owner;

    constructor(address _stableCoin1, address _stableCoin2, address _stableCoin3, address _stableCoin4, address _intToken) {
        stableCoin1 = _stableCoin1;
        stableCoin2 = _stableCoin2;
        stableCoin3 = _stableCoin3;
        stableCoin4 = _stableCoin4;
        intToken = Iint(_intToken);
        owner = msg.sender;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Only the owner can perform this action");
        _;
    }

    modifier timechainCompleted(address _protocolAddress) {
        require((block.timestamp - BurningPools[_protocolAddress].startingBlock) >= 7 days, "Timechains are not completed yet");
        _;
    }

    modifier hasRemainingINT(address _protocolAddress) {
        BurningPool storage pool = BurningPools[_protocolAddress];
        uint256 remainingINT = pool.totalInputs - pool.totalslashedAmount;
        require(remainingINT > 0, "No INT remaining to be claimed");
        _;
    }

    // Initialize the protocol's Burning pool with initial values
    function initializeBurningPool(address _protocolAddress, address usdUsed, uint256 _totalamount) external nonReentrant {
        require(_protocolAddress != address(0), "The address cannot be equal to zero address");
        require(usdUsed != address(0), "the address cannot be equal to zero address");
        require(_totalamount != 0, "the given amount cannot be equal to zero ");
        require(BurningPools[_protocolAddress].totalInputs == 0, "Burning pool already initialized");
        require(BurningPools[_protocolAddress].noOfinvestments == 0, "The pool is already initialized");
        require(usdUsed == stableCoin1 || usdUsed == stableCoin2 || usdUsed == stableCoin3 || usdUsed == stableCoin4, "The token used should be any one of them");
        BurningPools[_protocolAddress].totalInputs = _totalamount;
        BurningPools[_protocolAddress].timeChainsLeft = 50;
        BurningPools[_protocolAddress].slashingPercentage[1][_totalamount] = 2;
        BurningPools[_protocolAddress].noOfinvestments = 1;
        BurningPools[_protocolAddress].amountStaked[1] = _totalamount;
        BurningPools[_protocolAddress].usdUsed = usdUsed;
        BurningPools[_protocolAddress].startingBlock = block.timestamp;
        // Transfer the usd to this account, before that he needs to give approval for this contract
        IERC20(usdUsed).transferFrom(msg.sender, address(this), _totalamount);
    }

    // Function to add new inputs to the Burning pool
    function addInputsToBurningPool(address _protocolAddress, uint256 _totalamount) external nonReentrant {
        require(_protocolAddress != address(0), "The address cannot be equal to zero address");
        require(_totalamount != 0, "the given amount cannot be equal to zero ");
        BurningPool storage pool = BurningPools[_protocolAddress];

        // Calculate the slashing percentage for the new supply of INT
        uint256 slashingPercentage = 100 / pool.timeChainsLeft;

        // Update the Burning pool data with the new inputs and slashing percentage
        pool.totalInputs += _totalamount;
        pool.noOfinvestments += 1;
        pool.amountStaked[1] = _totalamount;
        pool.slashingPercentage[pool.noOfinvestments][_totalamount] = slashingPercentage;
        IERC20(pool.usdUsed).transferFrom(msg.sender, address(this), _totalamount);
    }

    // Function to slash the INT tokens based on the current timechain
    function slashTokens(address _protocolAddress) external nonReentrant {
        require(_protocolAddress != address(0), "The address cannot be equal to zero address");
        BurningPool storage pool = BurningPools[_protocolAddress];
        require(pool.timeChainsLeft > 0, "The Timechains needs to be greater than 0");
        uint completedTimeChains = (block.timestamp - pool.startingBlock) / 7 days;
        uint FinalTimeChainLeft = completedTimeChains - (50 - pool.timeChainsLeft);
        uint256 slashedAmount;
        for (uint i = 0; i <= pool.noOfinvestments; i++) {
            uint amountstaked = pool.amountStaked[i + 1];
            // Calculate the slashed amount for this period
            slashedAmount += (amountstaked * (pool.slashingPercentage[i + 1][amountstaked] * completedTimeChains)) / 100;
        }
        // Update the Burning pool's total inputs after slashing
        pool.totalslashedAmount += slashedAmount;
        // Add the slashed amount to the GLIPs vault
        glipsVaultAmount[msg.sender] += slashedAmount;
        // Decrease the number of timechains left
        pool.timeChainsLeft -= completedTimeChains;
        // send the amount to the glipsVault
        IERC20(pool.usdUsed).transfer(glipsVault, slashedAmount);
    }

    // Function to get the balance of INT available to spend at the start of the current timechain
    function getBalance(address _protocolAddress) external view returns (uint256) {
        require(_protocolAddress != address(0), "The address cannot be equal to zero address");
        BurningPool storage pool = BurningPools[_protocolAddress];
        return pool.totalInputs - pool.totalslashedAmount;
    }

    // Function to burn and claim the USD after the end of every timechain
    function burnAndClaim(uint256 amount) external nonReentrant {
        require(amount != 0, "Amount should be greater than 0");
        require(intToken.balanceOf(msg.sender) >= amount, "Not enough INT balance to burn");

        BurningPool storage pool = BurningPools[msg.sender];
        require((block.timestamp - pool.startingBlock) >= 7 days, "The timechain has not completed 7 days yet");

        address currentStableCoin = findGreatest(stableCoin1, stableCoin2, stableCoin3, stableCoin4);

        intToken.burn(amount);
        IERC20(currentStableCoin).transfer(msg.sender, amount);
    }

    // Function to find the greatest stablecoin balance among the four
    function findGreatest(address _stableCoin1, address _stableCoin2, address _stableCoin3, address _stableCoin4) public view returns (address) {
        address greatestCoin = _stableCoin1;
        uint256 greatestBalance = IERC20(_stableCoin1).balanceOf(address(this));

        if (IERC20(_stableCoin2).balanceOf(address(this)) > greatestBalance) {
            greatestCoin = _stableCoin2;
            greatestBalance = IERC20(_stableCoin2).balanceOf(address(this));
        }

        if (IERC20(_stableCoin3).balanceOf(address(this)) > greatestBalance) {
            greatestCoin = _stableCoin3;
            greatestBalance = IERC20(_stableCoin3).balanceOf(address(this));
        }

        if (IERC20(_stableCoin4).balanceOf(address(this)) > greatestBalance) {
            greatestCoin = _stableCoin4;
        }

        return greatestCoin;
    }
}
shivasai780 commented 1 year ago
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./Iint.sol";

contract TimechainProtocol is ReentrancyGuard{
    // Define the structure for the protocol's Burning pool
    struct BurningPool {
        uint256 totalInputs;
        uint256 timeChainsLeft;
        mapping(uint=>mapping(uint=>uint)) slashingPercentage;//slashingpercent[number of investment][Amount]=slashpercent
        mapping(uint => uint)amountStaked;
        uint256 noOfinvestments;
        address usdUsed;
        uint256 startingBlock;
        uint256 totalslashedAmount;
    }

    // Mapping to store the protocol's Burning pool data
    mapping(address => BurningPool) public BurningPools;

    // GLIPs vault to hold the slashed INT
    mapping(address => uint256) public glipsVaultAmount;

    address public stableCoin1;
    address public stableCoin2;
    address public stableCoin3;
    address public stableCoin4;
    address public glipsVault;
    Iint public intToken;
    address public owner;
    constructor(address _stableCoin1,address _stableCoin2,address _stableCoin3,address _stableCoin4,address _intToken) {
        stableCoin1 = _stableCoin1;
        stableCoin2=_stableCoin2;
        stableCoin3=_stableCoin3;
        stableCoin4=_stableCoin4;
        intToken=Iint(_intToken);
        owner = msg.sender;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Only the owner can perform this action");
        _;
    }
    // Initialize the protocol's Burning pool with initial values
    function initializeBurningPool(address _protocolAddress,address usdUsed,uint _totalamount) external nonReentrant{
        require(_protocolAddress!=address(0),"The address cannot be equal to zero address");
        require(usdUsed != address(0),"the address cannot be equal to zero address");
        require(_totalamount != 0,"the given amount cannot be equal to zero ");
        require(BurningPools[_protocolAddress].totalInputs == 0, "Burning pool already initialized");
        require(BurningPools[_protocolAddress].noOfinvestments == 0,"The pool is already initialized");
        require(usdUsed == stableCoin1 || usdUsed == stableCoin2 || usdUsed ==stableCoin3 || usdUsed == stableCoin4 ,"The tokem used should be any one of them");
        BurningPools[_protocolAddress].totalInputs=_totalamount;
        BurningPools[_protocolAddress].timeChainsLeft=50;
        BurningPools[_protocolAddress].slashingPercentage[1][_totalamount]=2;
        BurningPools[_protocolAddress].noOfinvestments=1;
        BurningPools[_protocolAddress].amountStaked[1]=_totalamount;
        BurningPools[_protocolAddress].usdUsed=usdUsed;
        BurningPools[_protocolAddress].startingBlock = block.timestamp;
        //transfer the usd to this account,before that he need to give the approval for this contract
        IERC20(usdUsed).transferFrom(msg.sender,address(this),_totalamount);

    }

    // Function to add new inputs to the Burning pool
    function addInputsToBurningPool(address _protocolAddress,uint _totalamount) external nonReentrant{
        require(_protocolAddress!=address(0),"The address cannot be equal to zero address");
        require(_totalamount != 0,"the given amount cannot be equal to zero ");
        BurningPool storage pool = BurningPools[_protocolAddress];

        // Calculate the slashing percentage for the new supply of INT
        uint256 slashingPercentage = 100 / pool.timeChainsLeft;

        // Update the Burning pool data with the new inputs and slashing percentage
        pool.totalInputs += _totalamount;
        pool.noOfinvestments +=1;
        pool.amountStaked[1]=_totalamount;
        pool.slashingPercentage[pool.noOfinvestments][_totalamount]=slashingPercentage;
        IERC20(pool.usdUsed).transferFrom(msg.sender,address(this),_totalamount);

    }

    // Function to slash the INT tokens based on the current timechain
    function slashTokens(address _protocolAddress) external nonReentrant{
        require(_protocolAddress!=address(0),"The address cannot be equal to zero address");
        BurningPool storage pool = BurningPools[_protocolAddress];
        require(pool.timeChainsLeft > 0,"The Timechains needs to be greater than 0");
        uint completedTimeChains= (block.timestamp - pool.startingBlock)/7 days;
        uint FinalTimeChainLeft=completedTimeChains-(50-pool.timeChainsLeft);
        uint256 slashedAmount;
        for(uint i= 0 ;i<=pool.noOfinvestments;i++)
        {
            uint amountstaked=pool.amountStaked[i+1];
             // Calculate the slashed amount for this period
            slashedAmount += (amountstaked * (pool.slashingPercentage[i+1][amountstaked]* completedTimeChains)) / 100;

        }
        // Update the Burning pool's total inputs after slashing
        pool.totalslashedAmount += slashedAmount;
         // Add the slashed amount to the GLIPs vault
        glipsVaultAmount[msg.sender] += slashedAmount;
        // Decrease the number of timechains left
        pool.timeChainsLeft -= completedTimeChains;
        //send the amount to the glipsVault
        IERC20(pool.usdUsed).transfer(glipsVault,slashedAmount);

    }

    // Function to get the balance of INT available to spend at the start of the current timechain
    function getBalance(address _protocolAddress) external view returns (uint256) {
        require(_protocolAddress!=address(0),"The address cannot be equal to zero address");
        BurningPool storage pool = BurningPools[_protocolAddress];
        return pool.totalInputs - pool.totalslashedAmount;
    }

    function burnandClaim(address _protocol,uint256 amount) external nonReentrant  {
        require(amount!=0,"The address cannot be equal to zero address");
        require(intToken.balanceOf(msg.sender)>= amount,"Not Sufficient Amount in your wallet");
        require(IERC20(stableCoin1).balanceOf(address(this))>=amount || IERC20(stableCoin2).balanceOf(address(this))>=amount || IERC20(stableCoin3).balanceOf(address(this))>=amount || IERC20(stableCoin4).balanceOf(address(this))>=amount,"No sufficient Amount in the pool");
        BurningPool storage pool = BurningPools[_protocolAddress];
        require((block.timestamp - pool.startingBlock) >= 7 days,"The timechain had till not completed");
        address currentStableCoin = findGreatest(stableCoin1, stableCoin2, stableCoin3, stableCoin4);
        intToken.transferFrom(msg.sender,address(this),amount);
        intToken.burn(amount);
        IERC20(currentStableCoin).transfer(msg.sender,amount);
    }

    function findGreatest(address _stableCoin1,address _stableCoin2,address _stableCoin3,address _stableCoin4) public view  returns (address) {
        // Using if-else statements
        address greatestCoin;

        if ( IERC20(_stableCoin1).balanceOf(address(this))>= IERC20(_stableCoin2).balanceOf(address(this)) && IERC20(_stableCoin1).balanceOf(address(this)) >= IERC20(_stableCoin3).balanceOf(address(this)) && IERC20(_stableCoin1).balanceOf(address(this)) >= IERC20(_stableCoin4).balanceOf(address(this))) {
            greatestCoin = _stableCoin1;
        } else if (IERC20(_stableCoin2).balanceOf(address(this)) >= IERC20(_stableCoin1).balanceOf(address(this)) && IERC20(_stableCoin2).balanceOf(address(this)) >= IERC20(_stableCoin3).balanceOf(address(this)) && IERC20(_stableCoin2).balanceOf(address(this)) >= IERC20(_stableCoin4).balanceOf(address(this))) {
            greatestCoin = _stableCoin2;
        } else if (IERC20(_stableCoin3).balanceOf(address(this)) >= IERC20(_stableCoin1).balanceOf(address(this)) && IERC20(_stableCoin3).balanceOf(address(this)) >= IERC20(_stableCoin2).balanceOf(address(this)) && IERC20(_stableCoin3).balanceOf(address(this)) >= IERC20(_stableCoin4).balanceOf(address(this))) {
            greatestCoin = _stableCoin3;
        } else {
            greatestCoin = _stableCoin4;
        }

        return greatestCoin;
    }
}
123456788940 commented 1 year ago

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

import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/utils/math/SafeMath.sol"; import "@openzeppelin/contracts/access/Ownable.sol";

contract TimechainProtocol is Ownable { using SafeMath for uint256;

struct BurningPool { uint256 totalInputs; uint256 timechainInterval; uint256 noOfTimechains; address usdUsed; uint256 startingBlock; }

mapping(address => BurningPool) public burningPools;

address[] public stableCoins; address public intToken;

constructor(address[] memory _stableCoins, address _intToken) { require(_stableCoins.length > 0, "No stable coins provided"); require(_intToken != address(0), "Invalid INT token address"); stableCoins = _stableCoins; intToken = _intToken; }

function initializeBurningPool(address _usdUsed, uint256 _totalAmount) external onlyOwner { require(_usdUsed != address(0), "Invalid token address"); require(_totalAmount > 0, "Total amount must be greater than zero");

burningPools[msg.sender] = BurningPool(_totalAmount, 7 days, 0, _usdUsed, block.timestamp);
IERC20(_usdUsed).transferFrom(msg.sender, address(this), _totalAmount);

}

function addInputsToBurningPool(uint256 _totalAmount) external { require(_totalAmount > 0, "Total amount must be greater than zero"); BurningPool storage pool = burningPools[msg.sender]; require(block.timestamp >= pool.startingBlock.add(pool.timechainInterval), "Cannot add inputs before the timechain interval is over");

pool.totalInputs = pool.totalInputs.add(_totalAmount);
pool.noOfTimechains = pool.noOfTimechains.add(1);
IERC20(pool.usdUsed).transferFrom(msg.sender, address(this), _totalAmount);
pool.startingBlock = block.timestamp;

}

function burnAndClaim() external { BurningPool storage pool = burningPools[msg.sender]; require(pool.noOfTimechains > 0, "Burning pool not initialized"); require(block.timestamp >= pool.startingBlock.add(pool.timechainInterval), "Cannot burn and claim before the timechain interval is over");

uint256 amount = IERC20(intToken).balanceOf(msg.sender);
require(amount > 0, "No INT to burn and claim");

address currentStableCoin = findGreatestStableCoin();
IERC20(intToken).transferFrom(msg.sender, address(this), amount);
IERC20(currentStableCoin).transfer(msg.sender, amount);

}

function getBalance() external view returns (uint256) { BurningPool storage pool = burningPools[msg.sender]; return pool.totalInputs; }

function findGreatestStableCoin() internal view returns (address) { address greatestCoin = stableCoins[0];

for (uint256 i = 1; i < stableCoins.length; i++) {
    if (IERC20(stableCoins[i]).balanceOf(address(this)) > IERC20(greatestCoin).balanceOf(address(this))) {
        greatestCoin = stableCoins[i];
    }
}

return greatestCoin;

} }