ETH Price: $2,110.36 (+0.85%)

Contract Diff Checker

Contract Name:
Rome

Contract Source Code:

File 1 of 1 : Rome

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

interface IERC20 {
    function totalSupply() external view returns (uint256);
    function balanceOf(address account) external view returns (uint256);
    function transfer(address recipient, uint256 amount) external returns (bool);
    function allowance(address owner, address spender) external view returns (uint256);
    function approve(address spender, uint256 amount) external returns (bool);
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external returns (bool);
   
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

interface IERC20Metadata is IERC20 {
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function decimals() external view returns (uint8);
}



library SafeMath {
    
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }
    
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }
    
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }
    
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }
    
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        return a + b;
    }


    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return a - b;
    }


    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        return a * b;
    }
    
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }


    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return a % b;
    }
    
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        unchecked {
            require(b <= a, errorMessage);
            return a - b;
        }
    }
    
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a / b;
        }
    }
    
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}

contract Rome {
    using SafeMath for uint256;
    string public name = "Vestmap Rome";
    IERC20 public  stakeToken;
    uint256 startDate;
    IERC20 public  rewardToken;
    uint public  totalPool;
    uint public  minstakeAmount;
     uint public  maxstakeAmount;
    bool public poolStatus;
    //declaring owner state variable
    address public owner;
    //declaring default APY (default 0.1% daily or 36.5% APY yearly)
    uint256 public defaultAPY = 24;
    uint256 public constant LOCK_PERIOD = 1104 hours;
     struct UserInfo {    
        uint256 stakeTime;
        uint256 amount;
    }

    //declaring total staked
    uint256 public totalStaked;
    //users staking balance
    mapping(address => uint256) public stakingBalance;
    //mapping list of users who ever staked
    mapping(address => bool) public hasStaked;
    //mapping list of users who are staking at the moment
    mapping(address => bool) public isStakingAtm;
     //array of all stakers
    address[] public stakers;
    mapping(address => UserInfo[]) public userInfo;
    
    constructor(IERC20  _stakeToken, IERC20 _rewardToken , uint _totalPool, bool  _poolStatus, uint _minstakeAmount, uint _maxstakeAmount)  payable {
        stakeToken = _stakeToken;
        startDate = block.timestamp;
        rewardToken = _rewardToken;
        totalPool = _totalPool * (10**18);
        poolStatus = _poolStatus;
        minstakeAmount = _minstakeAmount * (10**18);
        maxstakeAmount = _maxstakeAmount * (10**18);
        owner = msg.sender;
    }
     function changeTotalpool(uint256 _value) public {
        //only owner can issue airdrop
        require(msg.sender == owner, "Only contract creator can change Total pool");
        require(
            _value > 0,
            "Pool value has to be more than 0, try 100 for (0.100% daily) instead"
        );
        totalPool = _value * (10**18);
    }
     function changepoolStatus(bool _value) public {
        //only owner can issue airdrop
        require(msg.sender == owner, "Only contract creator can change Pool Status");
        poolStatus = _value;
    }
   
    //stake tokens function
     error InvalidAmount (uint256 totalreward,uint256 mins,uint256 rew);
     error Notstaked (string warning);
    
    function stakeTokens(uint256 _amount) public {        
        //must be more than 0
       require(_amount > 0, "amount cannot be 0");
       totalStaked = totalStaked + _amount;
       if(totalStaked>totalPool) {
            revert Notstaked({
                warning: "Warning! Pool limit is reached."
            }); 
        }
        if(minstakeAmount > _amount) {
           revert Notstaked({
                warning: "Warning! Your stake amount is lower than minimum stake amount"
            }); 
        }
        if(maxstakeAmount < _amount) {
           revert Notstaked({
                warning: "Warning! Your stake amount is bigger than maximum stake amount"
            }); 
        }
         if(poolStatus == false) {
                revert Notstaked({
                warning: "Warning! Pool status is closed."
            }); 
        }
        stakeToken.transferFrom(msg.sender, address(this), _amount);        
        stakingBalance[msg.sender] = stakingBalance[msg.sender] + _amount;
        userInfo[msg.sender].push(
            UserInfo(                
                block.timestamp,               
                 _amount
            )
        );
        //checking if user staked before or not, if NOT staked adding to array of stakers
        if (!hasStaked[msg.sender]) {
            stakers.push(msg.sender);
        }
     
    }
    //unstake tokens function
    function stakeCheck(address wallet) public view returns(uint256) {
        if(userInfo[wallet].length>0) {
            return 1;
        }
        else 
        {
           return 0;
        }
    }
        function timeCheck() public view returns(uint256) {
        if( startDate + LOCK_PERIOD <=   block.timestamp) {
            return 1;
        }
        else 
        {
           return 0;
        }
    }
    function unstakeTokens() public {
        require(userInfo[msg.sender].length>0," You don't have any stakes yet.");

        for (uint256 i = 0; i < userInfo[msg.sender].length; i++) {
        uint256 mins =0;
        require(startDate + LOCK_PERIOD <=   block.timestamp, " Too early to unstake");   
                uint256 balance = stakingBalance[msg.sender];
        uint256 divisor = 100000;   
        if (block.timestamp >= userInfo[msg.sender][i].stakeTime + LOCK_PERIOD) {
                    
                mins = (((startDate  + LOCK_PERIOD) - userInfo[msg.sender][i].stakeTime  )/60);
         
            }
        else {
            if ( userInfo[msg.sender][i].stakeTime>(startDate  + LOCK_PERIOD)) {
             mins = 0;
            }
      else {    
          mins = ((block.timestamp-userInfo[msg.sender][i].stakeTime)/60);     
             }   
         }
        uint256 hoursmultiplier = 365*24*60;
        uint256 custommultiplier = defaultAPY*divisor;
        uint256 totalreward = SafeMath.div(custommultiplier,hoursmultiplier);        
        uint256 reward = (balance/100)*totalreward;
       
        uint256 rew = SafeMath.div(reward,divisor)*mins;       
        totalStaked = totalStaked - balance;
        stakeToken.transfer(msg.sender, balance);
        rewardToken.transfer(msg.sender, rew);
        delete userInfo[msg.sender];
        //reseting users staking balance
        stakingBalance[msg.sender] = 0;
        //updating staking status
        isStakingAtm[msg.sender] = false;

        }
    }
    function gstartDate() public view returns(uint256) {
        return startDate;
    }
     function userRewards() public view returns(uint256) {
        uint256 totalrewards=0;
      for (uint256 i = 0; i < userInfo[msg.sender].length; i++) {
        uint256 mins =0;
        uint256 balance = stakingBalance[msg.sender];
        uint256 divisor = 100000;
        if (block.timestamp >= userInfo[msg.sender][i].stakeTime + LOCK_PERIOD) {
           
                
                mins = (((startDate  + LOCK_PERIOD) - userInfo[msg.sender][i].stakeTime  )/60);
          
            }
        else {
             if ( userInfo[msg.sender][i].stakeTime>(startDate  + LOCK_PERIOD)) {
             mins = 0;
            }
         else {
          mins = ((block.timestamp-userInfo[msg.sender][i].stakeTime)/60);        
            }
               
         }       
        uint256 hoursmultiplier = 365*24*60;
        uint256 custommultiplier = defaultAPY*divisor;
        uint256 totalreward = SafeMath.div(custommultiplier,hoursmultiplier);        
        uint256 reward = (balance/100)*totalreward;
        uint256 rew = SafeMath.div(reward,divisor)*mins;
        totalrewards += rew;
      }
       return totalrewards;
     }
    //change APY value for custom staking
    function changeAPY(uint256 _value) public {
        //only owner can issue airdrop
        require(msg.sender == owner, "Only contract creator can change APY");
        require(
            _value > 0,
            "APY value has to be more than 0, try 100 for (0.100% daily) instead"
        );
        defaultAPY = _value;
    }

}

Please enter a contract address above to load the contract details and source code.

Context size (optional):