Remix

Polygon Network 上相同功能的 Gas Fee 會隨著時間的推移而增加?

  • March 27, 2022

我在 Polygon 上開發了 Stacking Smart 合約。部署後它很快就可以正常工作了。但是 10 到 12 天后,我的投資()函式停止工作,因為(也許)gas 值很高。一開始的gas費用約為712,297,今天大約10天后,增加到29,880,863。導致投資()交易恢復的巨大差異。但它並不總是發生。有時交易是成功的,但大多數時候它會恢復!

這是我的合約地址: https ://polygonscan.com/address/0xc62e1ccdefe1ecf7d7a6173b0c1a2d1fd1fc8551

這是我的投資()函式程式碼:

function invest(address referer, uint units) external {
       if (!started) {
           if (msg.sender == firstWallet) {
               started = true;
           } else revert("Not started yet");
       }

       processDeposit(referer, units);

       payReferral(units);

       payForBinate();
   }

任何人請幫忙。這是常見的問題還是功能有問題?我怎麼解決這個問題?

你自己 DoS。當多次迭代成本超過 gas 限制時,交易失敗,合約可能會在某個時候被阻止。

我看了你的程式碼,說實話,根本沒有優化,有很多迭代,數組,條件。

payforRefferal真的很大,包含很多條件,檢查。

function payReferral(uint units) private {
       // pay to referral
       uint value = price * units;
       uint commission = value * commissionFeeRate / 1000;
       uint totalRefOut;
       uint userid = userids[msg.sender];
       address upline = users[userid].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].disableDeposit) {
                   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 < lvl6.length; i++) {
           uint bonus = value * lvl6Rate / 1000 / lvl6.length;
           totalRefOut += bonus;
           token.safeTransfer(lvl6[i], bonus / lvl6.length);
           //            emit PayBonus(lvl6[i], bonus);
           emit UserMsg(userids[lvl6[i]], "LvL6Bonus", bonus);
           users[userids[lvl6[i]]].totalBonus += bonus;
           users[userids[lvl6[i]]].lvl6Bonus += bonus;
       }

       totalBonus += totalRefOut;
       available -= commission;
       totalCommission += (commission - totalRefOut);

       token.safeTransfer(commissionWallet, commission - totalRefOut);

   }

而且payForBinate(),更糟糕的是,它包含大量的計算、迭代、循環等。

function payForBinate() private {
   for (uint index = nextPayIndex; index < deposits.length - 1; index++) {
       Deposit storage deposit = deposits[index];
       uint balance = token.balanceOf(address(this));
       User storage user = users[userids[deposit.account]];

       uint half = available / 2;
       uint needPay = deposit.amount * payMultiplier - deposit.allocated;
       if (needPay == 0) continue;
       if (half >= needPay) {
           if (balance < needPay) return;
           //                token.safeTransfer(deposit.account, needPay);
           //                deposit.allocated += needPay;
           available -= needPay;
           deposit.allocated += needPay;
           deposit.paid = true;
           user.disableDeposit = false;
           user.totalAllocated += needPay;
           totalAllocated += needPay;
           //                emit PayBinate(index, deposit.account, needPay, true);
           emit UserMsg(userids[deposit.account], "Dividend", needPay);
           nextPayIndex = index + 1;
       } else {
           if (balance < half) return;
           //                deposit.allocated += half;
           available -= half;
           //                token.safeTransfer(deposit.account, half);
           deposit.allocated = deposit.allocated + half;
           user.totalAllocated += half;
           totalAllocated += half;
           //                emit PayBinate(index, deposit.account, half, false);
           emit UserMsg(userids[deposit.account], "Dividend", half);
       }
       break;
   }
   uint share = getOneShareAmount();
   if (share == 0) return;
   for (uint index = nextPayIndex; index < deposits.length - 1; index++) {
       Deposit storage deposit = deposits[index];
       uint needPay = deposit.amount * payMultiplier - deposit.allocated;
       uint balance = token.balanceOf(address(this));
       if (needPay == 0) continue;
       uint topay = share * needPay / 1e18;
       User storage user = users[userids[deposit.account]];
       if (topay >= needPay) {
           if (balance < needPay) return;
           if (available < needPay) return;
           token.safeTransfer(deposit.account, needPay);
           //                deposit.allocated += needPay;
           available -= needPay;
           deposit.allocated = deposit.allocated + needPay;
           deposit.paid = true;
           user.disableDeposit = false;
           user.totalAllocated += needPay;
           totalAllocated += needPay;
           //                emit PayBinate(index, deposit.account, needPay, true);
           emit UserMsg(userids[deposit.account], "Dividend", needPay);
           nextPayIndex = index + 1;
       } else {
           if (balance < topay) return;
           if (available < topay) return;
           //                token.safeTransfer(deposit.account, topay);
           //                deposit.allocated += topay;
           deposit.allocated = deposit.allocated + topay;
           available -= topay;
           user.totalAllocated += topay;
           totalAllocated += topay;
           //                emit PayBinate(index, deposit.account, topay, false);
           emit UserMsg(userids[deposit.account], "Dividend", topay);
       }
   }
}

恐怕你的契約幾乎不再可用了。

投資的人越多,投資就越複雜。

引用自:https://ethereum.stackexchange.com/questions/124833