可靠性:事件已触发,但代表调用后状态未更新

时间:2018-12-05 09:46:44

标签: ethereum solidity

我想使用delegatecall将ETH存入WETH,并将此过程与其他操作一起批处理(请参见下面的代码)。运行松露测试时,似乎事件已正确触发,但状态似乎未更新。

Rinkeby网络上的行为相同。奇怪的是,事务完全成功完成。以下是交易示例:https://rinkeby.etherscan.io/tx/0x93c724174e2b70f2257544ebc0e0b9da6e31a7a752872da7683711bd4d4bd92b

实体代码:

pragma solidity 0.4.24;

import "../interfaces/ERC20.sol";
import "./WETH9.sol";

contract SetupAccount {

address public exchangeAddress;
address public wethAddress;

constructor (
    address _exchangeAddress,
    address _wethAddress
) public {
    exchangeAddress = _exchangeAddress;
    wethAddress = _wethAddress;
}


function setup(
    address[] _tokenAddresses, 
    uint256[] _values
) public payable {
    for (uint i = 0; i < _tokenAddresses.length; i++) {
        _tokenAddresses[i].delegatecall(abi.encodeWithSignature("approve(address,uint256)", exchangeAddress, _values[i]));
    }

    if (msg.value != 0) {
        wethAddress.delegatecall(abi.encodeWithSignature("deposit()"));
    }
}

松露测试失败:

  describe('setupAccount', async () => {
    beforeEach(async () => {
      weth = await WETH.new()
      exchange = await Exchange.new(rewardAccount)
      bnb = await BNB.new(user1, 1000)
      dai = await DAI.new(user1, 1000)
      omg = await OMG.new(user1, 1000)
      setupAccount = await SetupAccount.new(exchange.address, weth.address)
    })

    it('setupAccount should deposit weth and approve tokens', async () => {
      await setupAccount.setup(
        [bnb.address, dai.address, omg.address],
        [1000, 1000, 1000],
        { from: user1, value: 10 ** 18 }
      )

      let wethBalance = await weth.balanceOf(user1)

      wethBalance.should.be.bignumber.equal(10 ** 18)
      bnbAllowance.should.be.bignumber.equal(1000)
      daiAllowance.should.be.bignumber.equal(1000)
      omgAllowance.should.be.bignumber.equal(1000)
    })
  })

测试期间发出的事件:

Events emitted during test:
---------------------------

Deposit(dst: <indexed>, wad: 1000000000000000000)

---------------------------

测试结果:

  1) Contract: SetupAccount
       setupAccount
         setupAccount should deposit weth and approve tokens:

      AssertionError: expected '0' to equal '1000000000000000000'
      + expected - actual

      -0
      +1000000000000000000

我对为什么这不起作用感到困惑。谢谢你。

1 个答案:

答案 0 :(得分:0)

msg.value是通过delegatecall正确保留的。下面的代码演示了这一点,如发出的事件显示正确的值所证明。

pragma solidity >0.4.99 <0.6;

contract Target {
    event Received(uint256 amount);

    function deposit() external payable {
        emit Received(msg.value);
    }
}

contract Delegater {
    function deposit() external payable {
        (bool success,) = address(new Target()).delegatecall(abi.encodeWithSignature("deposit()"));
        require(success);
    }
}