气体估计失败:内部JSON-RPC错误(代码3)

发布于 2025-01-22 14:44:36 字数 13773 浏览 0 评论 0原文

我创建了一份用于堆叠投资的池合同。但是,当我用混音IDE部署在TestNet上,并且尝试执行函数投资时,我遇到了此内部JSON-RPC错误。伙计们,请帮助我找到整​​个代码中的问题。这是完整代码:

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

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

contract StarzBit is Ownable {
    using SafeERC20 for IERC20;

    struct Deposit {
        uint index;
        uint checkpoint;
    }

    struct User {
        address referer;
        address account;
        Deposit[] deposits;
        uint[] partners;
        uint totalDeposit;
        uint totalWithdrawn;
        uint totalBonus;
        uint directBonus;
        uint teamBonus;
        uint checkpoint;
    }

    struct Level {
        uint level;
        uint lvl0; // partner
        uint lvl1;
        uint lvl2;
        uint lvl3;
        uint lvl4;
        uint team; // total Team count
    }

    IERC20 public token;
    uint public price;
    uint public maxUnits = 2;
    uint public minUnits = 1;
    uint public totalDeposit;
    uint public depositCount;
    uint public totalBonus;
    uint public totalWithdrawn;
    uint public totalCommission;
    uint public totalUsers;
    uint public commissionFeeRate = 100;
    uint public levelStep = 3;

    uint[] public referRate = [8, 5, 3, 2];
    address[] public team;
    uint public teamRate = 20;
    uint public marketingFee = 50;
    address public marketingWallet = 0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2;
    address public firstWallet = 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4;
    bool enabled = false;

    mapping(address => uint) public userids;
    mapping(uint => User) public users;
    mapping(uint => Level) public levels;
    mapping(uint => address) public depositIndexToAccount;

    event UserMsg(uint userid, string msg, uint value);
    event Commission(uint value);

    constructor(IERC20 _token, uint _price) {
        token = _token;
        price = _price;
    }

    receive() external payable {}

    function invest(address referer, uint units) external {
        require(enabled, "Pool Not Enabled");
        require(units >= minUnits, "Less than Min Units");
        require(units <= maxUnits, "Over than Max Units");

        uint userid = userids[msg.sender];
        if (userid == 0) {
            totalUsers += 1;
            userid = totalUsers;
            userids[msg.sender] = userid;
            emit UserMsg(userid, "Joined", 0);
        }

        User storage user = users[userid];
        if (user.account == address(0)) {
            user.account = msg.sender;
            user.checkpoint = block.timestamp;
        }

        if (user.referer == address(0) && referer != address(0)) {
            if (users[userids[referer]].totalDeposit > 0 && referer != msg.sender && user.totalDeposit == 0) {
                user.referer = referer;
                users[userids[referer]].partners.push(userid);
                processLevelUpdate(referer, msg.sender);

                address parent = referer;
                for (uint i = 0; i < 5; i++) {
                    if (parent == address(0)) break;
                    levels[userids[parent]].team += 1;
                    parent = users[userids[parent]].referer;
                }
            }
        }
        // uint value;
        // payForCommission(referer, value);
        processDeposit(units);
        payReferral(referer, units);
    }

    function payForCommission(address referer, uint value) private returns (uint){
        address upline = referer;

        uint totalRefOut;
        for (uint i = 0; i < referRate.length; i++) {
            uint uplineId = userids[upline];
            if (uplineId == 0) break;
            if (upline != address(0) && levels[uplineId].level > i) {
                    uint bonus = value * referRate[i] / 1000;
                    totalRefOut = totalRefOut + bonus;
                    token.safeTransfer(upline, bonus);
                    //                    emit PayBonus(upline, bonus);
                    emit UserMsg(uplineId, "RefBonus", bonus);
                    users[uplineId].totalBonus += bonus;
                    if (i == 0) {
                        users[uplineId].directBonus += bonus;
                    }
                
                upline = users[uplineId].referer;
            } else break;
        }

        for (uint i = 0; i < team.length; i++) {
            uint bonus = value * teamRate / 1000 / team.length;
            totalRefOut += bonus;
            token.safeTransfer(team[i], bonus / team.length);
            //            emit PayBonus(team[i], bonus);
            emit UserMsg(userids[team[i]], "TeamBonus", bonus);
            users[userids[team[i]]].totalBonus += bonus;
            users[userids[team[i]]].teamBonus += bonus;
        }
        
        totalBonus += totalRefOut;
        uint marketingOut = value * marketingFee / 1000;
        token.safeTransfer(marketingWallet, marketingOut);

        uint commi = totalRefOut + marketingOut;
        emit Commission(commi);
        return commi;
    }

    function getCommissionRate() public view returns(uint) {
            return commissionFeeRate;
        }

    function payReferral(address referer, uint units) private {
        // pay to referral
        uint value = price * units;
        uint commission = value * commissionFeeRate / 1000;
        uint totalRefOut;

        address upline = referer;

        for (uint i = 0; i < referRate.length; i++) {
            uint uplineId = userids[upline];
            if (uplineId == 0) break;
            if (upline != address(0) && levels[uplineId].level > i) {
                if (users[uplineId].totalDeposit > users[uplineId].totalWithdrawn) {
                    uint bonus = value * referRate[i] / 1000;
                    totalRefOut = totalRefOut + bonus;
                    token.safeTransfer(upline, bonus);
                    //                    emit PayBonus(upline, bonus);
                    emit UserMsg(uplineId, "RefBonus", bonus);
                    users[uplineId].totalBonus += bonus;
                    if (i == 0) {
                        users[uplineId].directBonus += bonus;
                    }
                }
                upline = users[uplineId].referer;
            } else break;
        }

        for (uint i = 0; i < team.length; i++) {
            uint bonus = value * teamRate / 1000 / team.length;
            totalRefOut += bonus;
            token.safeTransfer(team[i], bonus / team.length);
            //            emit PayBonus(team[i], bonus);
            emit UserMsg(userids[team[i]], "TeamBonus", bonus);
            users[userids[team[i]]].totalBonus += bonus;
            users[userids[team[i]]].teamBonus += bonus;
        }

        uint commi = commission - totalRefOut;
        token.safeTransfer(marketingWallet, commi);
        emit Commission(commi);
        totalBonus += totalRefOut;
        totalCommission += commission;
    }

    function processLevelUpdate(address referer, address from) private {
        if (referer == address(0)) return;
        uint refererid = userids[referer];
        if (refererid == 0) return;
        uint fromid = userids[from];

        User storage user = users[refererid];
        Level storage level = levels[refererid];

        if (levels[fromid].level == 0) {
            level.lvl0++;
            if (level.lvl0 >= levelStep && level.level < 1) {
                level.level = 1;
                emit UserMsg(refererid, "LevelUp", 1);
                processLevelUpdate(user.referer, referer);
            }
        } else if (levels[fromid].level == 1) {
            level.lvl1++;
            if (level.lvl1 >= levelStep && level.level < 2) {
                level.level = 2;
                emit UserMsg(userids[referer], "LevelUp", 2);
                processLevelUpdate(user.referer, referer);
            }
        } else if (levels[fromid].level == 2) {
            level.lvl2++;
            if (level.lvl2 >= levelStep && level.level < 3) {
                level.level = 3;
                emit UserMsg(userids[referer], "LevelUp", 3);
                processLevelUpdate(user.referer, referer);
            }
        } else if (levels[fromid].level == 3) {
            level.lvl3++;
            if (level.lvl3 >= levelStep && level.level < 4) {
                level.level = 4;
                emit UserMsg(userids[referer], "LevelUp", 4);
                processLevelUpdate(user.referer, referer);
            }
        } else if (levels[fromid].level == 4) {
            level.lvl4++;
            if (level.lvl4 >= levelStep && level.level < 5) {
                level.level = 5;
                emit UserMsg(userids[referer], "LevelUp", 5);
                processLevelUpdate(user.referer, referer);
            }
        } 
    }

    function processDeposit(uint units) private returns (uint value) {
        uint userid = userids[msg.sender];
        User storage user = users[userid];
        require(userAllocated(msg.sender) >= user.totalDeposit, "Less Allocated");

        value = units * price;
        token.safeTransferFrom(msg.sender, address(this), value);
        totalDeposit += value;

        emit UserMsg(userid, "Deposit", value);

        for (uint i = 0; i < units; i++) {
            Deposit memory deposit = Deposit(depositCount + i, block.timestamp);
            user.deposits.push(deposit);
            depositIndexToAccount[depositCount + i] = msg.sender;
            // push deposit nature index
        }
        
        depositCount += units;
        user.totalDeposit += value;
    }

    function claim() external {
        uint userid = userids[msg.sender];
        User storage user = users[userid];
        uint allocated = userAllocated(msg.sender);
        require(allocated > user.totalWithdrawn, "No more allocated");
        uint topay = allocated - user.totalWithdrawn;
        user.totalWithdrawn += topay;
        totalWithdrawn += topay;
        emit UserMsg(userid, "Claim", topay);
    }

    function userAllocated(address account) public view returns (uint) {
        if (depositCount < 1) return 0;
        uint userid = userids[account];
        User storage user = users[userid];
        uint weight;
        for (uint i = 0; i < user.deposits.length; i += 1) {
            weight += (depositCount - user.deposits[i].index);
        }
        return totalDeposit * weight / totalWeight();
    }

    function userPercent(address account) public view returns (uint) {
        return userWeight(account) * depositCount * 100 / totalWeight();
    }

    function userWeight(address account) public view returns (uint) {
        uint userid = userids[account];
        User storage user = users[userid];
        uint weight;
        for (uint i = 0; i < user.deposits.length; i += 1) {
            weight += (depositCount - user.deposits[i].index);
        }
        return weight;
    }

    function totalWeight() public view returns (uint) {
        return depositCount * (depositCount + 1) / 2;
    }

    function userInfoById(uint id) public view returns(uint, uint, User memory, Level memory) {
        User storage user = users[id];
        Level storage level = levels[id];
        return (id, userids[user.referer], user, level);
    }

    function userInfoByAddress(address account) public view returns(uint, uint, User memory, Level memory) {
        uint userid = userids[account];
        return userInfoById(userid);
    }

    function partnerIdsById(uint id) public view returns (uint[] memory){
        User storage user = users[id];
        return user.partners;
    }

    function withdraw(uint amount) external onlyOwner {
        if (address(this).balance > 0) {
            payable(msg.sender).transfer(address(this).balance);
        }
        if (token.balanceOf(address(this)) > 0) {
            token.safeTransfer(msg.sender, amount);
        }
    }

    function setCommissionFeeRate(uint rate) external onlyOwner {
        commissionFeeRate = rate;
    }

    function setReferRate(uint[] memory rates) external onlyOwner {
        referRate = rates;
    }

    function setLevelStep(uint step) external onlyOwner {
        levelStep = step;
    }

    function levelteam() public view returns (address [] memory) {
        return team;
    }

    function setMarketingWallet(address wallet) external onlyOwner {
        marketingWallet = wallet;
    }

    function setEnabled(bool action) external onlyOwner {
        enabled = action;
    }

    function setToken(IERC20 _token) external onlyOwner {
        token = _token;
    }

    function setPrice(uint _price) external onlyOwner {
        price = _price;
    }

    function setMaxUnits(uint units) external onlyOwner {
        maxUnits = units;
    }

    function setMinUnits(uint units) external onlyOwner {
        minUnits = units;
    }

    function setMarketingFee(uint fee) external onlyOwner {
        marketingFee = fee;
    }

    function siteInfo() external view returns (uint, uint, uint, uint, uint, uint, uint, uint, bool) {
        return (price, minUnits, maxUnits, totalDeposit, depositCount, totalBonus, totalWithdrawn, totalUsers, enabled);
    }
}

这样的错误显示:

单击以查看图像

I created a pool contract for stacking invest. But when I deployed on testnet with Remix IDE and I trying to execute function invest, I got this Internal JSON-RPC Error. Guys please help me to find where is the problem in the entire code. Here is the full code:

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

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

contract StarzBit is Ownable {
    using SafeERC20 for IERC20;

    struct Deposit {
        uint index;
        uint checkpoint;
    }

    struct User {
        address referer;
        address account;
        Deposit[] deposits;
        uint[] partners;
        uint totalDeposit;
        uint totalWithdrawn;
        uint totalBonus;
        uint directBonus;
        uint teamBonus;
        uint checkpoint;
    }

    struct Level {
        uint level;
        uint lvl0; // partner
        uint lvl1;
        uint lvl2;
        uint lvl3;
        uint lvl4;
        uint team; // total Team count
    }

    IERC20 public token;
    uint public price;
    uint public maxUnits = 2;
    uint public minUnits = 1;
    uint public totalDeposit;
    uint public depositCount;
    uint public totalBonus;
    uint public totalWithdrawn;
    uint public totalCommission;
    uint public totalUsers;
    uint public commissionFeeRate = 100;
    uint public levelStep = 3;

    uint[] public referRate = [8, 5, 3, 2];
    address[] public team;
    uint public teamRate = 20;
    uint public marketingFee = 50;
    address public marketingWallet = 0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2;
    address public firstWallet = 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4;
    bool enabled = false;

    mapping(address => uint) public userids;
    mapping(uint => User) public users;
    mapping(uint => Level) public levels;
    mapping(uint => address) public depositIndexToAccount;

    event UserMsg(uint userid, string msg, uint value);
    event Commission(uint value);

    constructor(IERC20 _token, uint _price) {
        token = _token;
        price = _price;
    }

    receive() external payable {}

    function invest(address referer, uint units) external {
        require(enabled, "Pool Not Enabled");
        require(units >= minUnits, "Less than Min Units");
        require(units <= maxUnits, "Over than Max Units");

        uint userid = userids[msg.sender];
        if (userid == 0) {
            totalUsers += 1;
            userid = totalUsers;
            userids[msg.sender] = userid;
            emit UserMsg(userid, "Joined", 0);
        }

        User storage user = users[userid];
        if (user.account == address(0)) {
            user.account = msg.sender;
            user.checkpoint = block.timestamp;
        }

        if (user.referer == address(0) && referer != address(0)) {
            if (users[userids[referer]].totalDeposit > 0 && referer != msg.sender && user.totalDeposit == 0) {
                user.referer = referer;
                users[userids[referer]].partners.push(userid);
                processLevelUpdate(referer, msg.sender);

                address parent = referer;
                for (uint i = 0; i < 5; i++) {
                    if (parent == address(0)) break;
                    levels[userids[parent]].team += 1;
                    parent = users[userids[parent]].referer;
                }
            }
        }
        // uint value;
        // payForCommission(referer, value);
        processDeposit(units);
        payReferral(referer, units);
    }

    function payForCommission(address referer, uint value) private returns (uint){
        address upline = referer;

        uint totalRefOut;
        for (uint i = 0; i < referRate.length; i++) {
            uint uplineId = userids[upline];
            if (uplineId == 0) break;
            if (upline != address(0) && levels[uplineId].level > i) {
                    uint bonus = value * referRate[i] / 1000;
                    totalRefOut = totalRefOut + bonus;
                    token.safeTransfer(upline, bonus);
                    //                    emit PayBonus(upline, bonus);
                    emit UserMsg(uplineId, "RefBonus", bonus);
                    users[uplineId].totalBonus += bonus;
                    if (i == 0) {
                        users[uplineId].directBonus += bonus;
                    }
                
                upline = users[uplineId].referer;
            } else break;
        }

        for (uint i = 0; i < team.length; i++) {
            uint bonus = value * teamRate / 1000 / team.length;
            totalRefOut += bonus;
            token.safeTransfer(team[i], bonus / team.length);
            //            emit PayBonus(team[i], bonus);
            emit UserMsg(userids[team[i]], "TeamBonus", bonus);
            users[userids[team[i]]].totalBonus += bonus;
            users[userids[team[i]]].teamBonus += bonus;
        }
        
        totalBonus += totalRefOut;
        uint marketingOut = value * marketingFee / 1000;
        token.safeTransfer(marketingWallet, marketingOut);

        uint commi = totalRefOut + marketingOut;
        emit Commission(commi);
        return commi;
    }

    function getCommissionRate() public view returns(uint) {
            return commissionFeeRate;
        }

    function payReferral(address referer, uint units) private {
        // pay to referral
        uint value = price * units;
        uint commission = value * commissionFeeRate / 1000;
        uint totalRefOut;

        address upline = referer;

        for (uint i = 0; i < referRate.length; i++) {
            uint uplineId = userids[upline];
            if (uplineId == 0) break;
            if (upline != address(0) && levels[uplineId].level > i) {
                if (users[uplineId].totalDeposit > users[uplineId].totalWithdrawn) {
                    uint bonus = value * referRate[i] / 1000;
                    totalRefOut = totalRefOut + bonus;
                    token.safeTransfer(upline, bonus);
                    //                    emit PayBonus(upline, bonus);
                    emit UserMsg(uplineId, "RefBonus", bonus);
                    users[uplineId].totalBonus += bonus;
                    if (i == 0) {
                        users[uplineId].directBonus += bonus;
                    }
                }
                upline = users[uplineId].referer;
            } else break;
        }

        for (uint i = 0; i < team.length; i++) {
            uint bonus = value * teamRate / 1000 / team.length;
            totalRefOut += bonus;
            token.safeTransfer(team[i], bonus / team.length);
            //            emit PayBonus(team[i], bonus);
            emit UserMsg(userids[team[i]], "TeamBonus", bonus);
            users[userids[team[i]]].totalBonus += bonus;
            users[userids[team[i]]].teamBonus += bonus;
        }

        uint commi = commission - totalRefOut;
        token.safeTransfer(marketingWallet, commi);
        emit Commission(commi);
        totalBonus += totalRefOut;
        totalCommission += commission;
    }

    function processLevelUpdate(address referer, address from) private {
        if (referer == address(0)) return;
        uint refererid = userids[referer];
        if (refererid == 0) return;
        uint fromid = userids[from];

        User storage user = users[refererid];
        Level storage level = levels[refererid];

        if (levels[fromid].level == 0) {
            level.lvl0++;
            if (level.lvl0 >= levelStep && level.level < 1) {
                level.level = 1;
                emit UserMsg(refererid, "LevelUp", 1);
                processLevelUpdate(user.referer, referer);
            }
        } else if (levels[fromid].level == 1) {
            level.lvl1++;
            if (level.lvl1 >= levelStep && level.level < 2) {
                level.level = 2;
                emit UserMsg(userids[referer], "LevelUp", 2);
                processLevelUpdate(user.referer, referer);
            }
        } else if (levels[fromid].level == 2) {
            level.lvl2++;
            if (level.lvl2 >= levelStep && level.level < 3) {
                level.level = 3;
                emit UserMsg(userids[referer], "LevelUp", 3);
                processLevelUpdate(user.referer, referer);
            }
        } else if (levels[fromid].level == 3) {
            level.lvl3++;
            if (level.lvl3 >= levelStep && level.level < 4) {
                level.level = 4;
                emit UserMsg(userids[referer], "LevelUp", 4);
                processLevelUpdate(user.referer, referer);
            }
        } else if (levels[fromid].level == 4) {
            level.lvl4++;
            if (level.lvl4 >= levelStep && level.level < 5) {
                level.level = 5;
                emit UserMsg(userids[referer], "LevelUp", 5);
                processLevelUpdate(user.referer, referer);
            }
        } 
    }

    function processDeposit(uint units) private returns (uint value) {
        uint userid = userids[msg.sender];
        User storage user = users[userid];
        require(userAllocated(msg.sender) >= user.totalDeposit, "Less Allocated");

        value = units * price;
        token.safeTransferFrom(msg.sender, address(this), value);
        totalDeposit += value;

        emit UserMsg(userid, "Deposit", value);

        for (uint i = 0; i < units; i++) {
            Deposit memory deposit = Deposit(depositCount + i, block.timestamp);
            user.deposits.push(deposit);
            depositIndexToAccount[depositCount + i] = msg.sender;
            // push deposit nature index
        }
        
        depositCount += units;
        user.totalDeposit += value;
    }

    function claim() external {
        uint userid = userids[msg.sender];
        User storage user = users[userid];
        uint allocated = userAllocated(msg.sender);
        require(allocated > user.totalWithdrawn, "No more allocated");
        uint topay = allocated - user.totalWithdrawn;
        user.totalWithdrawn += topay;
        totalWithdrawn += topay;
        emit UserMsg(userid, "Claim", topay);
    }

    function userAllocated(address account) public view returns (uint) {
        if (depositCount < 1) return 0;
        uint userid = userids[account];
        User storage user = users[userid];
        uint weight;
        for (uint i = 0; i < user.deposits.length; i += 1) {
            weight += (depositCount - user.deposits[i].index);
        }
        return totalDeposit * weight / totalWeight();
    }

    function userPercent(address account) public view returns (uint) {
        return userWeight(account) * depositCount * 100 / totalWeight();
    }

    function userWeight(address account) public view returns (uint) {
        uint userid = userids[account];
        User storage user = users[userid];
        uint weight;
        for (uint i = 0; i < user.deposits.length; i += 1) {
            weight += (depositCount - user.deposits[i].index);
        }
        return weight;
    }

    function totalWeight() public view returns (uint) {
        return depositCount * (depositCount + 1) / 2;
    }

    function userInfoById(uint id) public view returns(uint, uint, User memory, Level memory) {
        User storage user = users[id];
        Level storage level = levels[id];
        return (id, userids[user.referer], user, level);
    }

    function userInfoByAddress(address account) public view returns(uint, uint, User memory, Level memory) {
        uint userid = userids[account];
        return userInfoById(userid);
    }

    function partnerIdsById(uint id) public view returns (uint[] memory){
        User storage user = users[id];
        return user.partners;
    }

    function withdraw(uint amount) external onlyOwner {
        if (address(this).balance > 0) {
            payable(msg.sender).transfer(address(this).balance);
        }
        if (token.balanceOf(address(this)) > 0) {
            token.safeTransfer(msg.sender, amount);
        }
    }

    function setCommissionFeeRate(uint rate) external onlyOwner {
        commissionFeeRate = rate;
    }

    function setReferRate(uint[] memory rates) external onlyOwner {
        referRate = rates;
    }

    function setLevelStep(uint step) external onlyOwner {
        levelStep = step;
    }

    function levelteam() public view returns (address [] memory) {
        return team;
    }

    function setMarketingWallet(address wallet) external onlyOwner {
        marketingWallet = wallet;
    }

    function setEnabled(bool action) external onlyOwner {
        enabled = action;
    }

    function setToken(IERC20 _token) external onlyOwner {
        token = _token;
    }

    function setPrice(uint _price) external onlyOwner {
        price = _price;
    }

    function setMaxUnits(uint units) external onlyOwner {
        maxUnits = units;
    }

    function setMinUnits(uint units) external onlyOwner {
        minUnits = units;
    }

    function setMarketingFee(uint fee) external onlyOwner {
        marketingFee = fee;
    }

    function siteInfo() external view returns (uint, uint, uint, uint, uint, uint, uint, uint, bool) {
        return (price, minUnits, maxUnits, totalDeposit, depositCount, totalBonus, totalWithdrawn, totalUsers, enabled);
    }
}

The error show like this:

click to see image

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文