Солидность: события срабатывают, но состояние не обновляется после делегатского вызова - PullRequest
0 голосов
/ 05 декабря 2018

Я хотел бы использовать 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 голосов
/ 05 декабря 2018

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);
    }
}
...