Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

合约变量写入异常 #882

Closed
fiboswap opened this issue Apr 29, 2022 · 4 comments
Closed

合约变量写入异常 #882

fiboswap opened this issue Apr 29, 2022 · 4 comments
Assignees
Labels
question Further information is requested

Comments

@fiboswap
Copy link

System information

Geth version: geth version
OS & Version: OSX
Commit hash : 0x557aae04475cfd47c1107b3a504490f438bc829f66d439ce913ba8be43c9ce33

Expected behaviour

合约地址:0x6a627aa43836ce66a4ee8767bfc432e1f9a94af6

合约 里同样的 算法
当最后一步设置为保存计算结果时,交易会出现很高评率的失败,并且失败的执行在 estimateGas 调用中并不会报错

经过上百笔的 生产测试后

我们明确 该问题仅出现在 合约 修改变量时执行报错

出现异常的接口

function upDateNet() public lock {
        uint time = block.timestamp;
        uint256 _min = minerPool.mining(time);
        uint256 _newEarn = _min - beforeEarnTokenBalance;
        (,,_newEarn) = minerRate(_newEarn);
        if ( _newEarn > 0 ) {
            uint _deRewards = (EPX_RATE - shareNetRateEPX_RATE) * _newEarn / EPX_RATE;
            _newEarn -= _deRewards;
            if ( totalDeposits > 0 ) { 
                uint mulD = EPX * _deRewards;
                uint divD = mulD / totalDeposits;
                // 这里 对 depositsNetEPX1 变量累加操作
                // depositsNetEPX1 += divD;
                _addDepositiNet(divD);
           
            }
            if ( totalShare > 0 ) {
                _addShareNet(EPX * _newEarn / totalShare);
            }
            beforeEarnTokenBalance = _min;
        }
    }

不会报错的接口

    event UpDate(uint min, uint balance, uint time);
    function upDateNet1() public returns(uint _depositsNetEPX1, uint _shareNet1) {
        uint time = block.timestamp;
        uint256 _min = minerPool.mining(time);
        emit UpDate(_min, beforeEarnTokenBalance, time);
        uint256 _newEarn = _min - beforeEarnTokenBalance;
        (,,_newEarn) = minerRate(_newEarn);
        if ( _newEarn > 0 ) {
            uint _deRewards = (EPX_RATE - shareNetRateEPX_RATE) * _newEarn / EPX_RATE;
            _newEarn -= _deRewards;
            if ( totalDeposits > 0 ) { 
                _depositsNetEPX1 += EPX * _deRewards / totalDeposits;
            }
            if ( totalShare > 0 ) {
                _shareNet1 += EPX * _newEarn / totalShare;
            }
        }
    }

两个接口的却别仅只是 对 变量 depositsNetEPX1 是否写入

该问题按一定概率出现 需要多次连续调用

这个问题再多个合约中都出现过,但概率很低,只有这个合约,在升级后合约后高频率出现该问题

@wellttllew
Copy link

https://bscscan.com/vmtrace?txhash=0xcd5460ab033e618ddc9d3002c6d49f4e5ecab3366b53c068172a7ee174653bf1&type=gethtrace2

revert reason 里面说的是 out of gas

estimate gas 可能和实际执行的所需要的不同。

ps: 举个例子,sstore 在写入一个 slot 的时候, gas cost 和之前这个 slot 存的是什么有关系

check this: https://hackmd.io/@fvictorio/gas-costs-after-berlin

@pythonberg1997 pythonberg1997 self-assigned this Apr 29, 2022
@pythonberg1997 pythonberg1997 added the question Further information is requested label Apr 29, 2022
@pythonberg1997
Copy link
Contributor

Exactly, @wellttllew is right. Thanks so much.

@zhangyi999
Copy link

谢谢

@lochjin
Copy link
Contributor

lochjin commented May 5, 2022

https://bscscan.com/vmtrace?txhash=0xcd5460ab033e618ddc9d3002c6d49f4e5ecab3366b53c068172a7ee174653bf1&type=gethtrace2

revert reason 里面说的是 out of gas

estimate gas 可能和实际执行的所需要的不同。

ps: 举个例子,sstore 在写入一个 slot 的时候, gas cost 和之前这个 slot 存的是什么有关系

check this: https://hackmd.io/@fvictorio/gas-costs-after-berlin

BSC暂时还没有柏林分叉
他的问题本质上是因为 RPC EstimateGas 接口所估算的值和实际相差太大,高频次的调用很容易重现。
#893

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

5 participants