солидность делегат предотвращение вызовов не работает

Я новичок, изучающий коды github uniswap v3. Я придумал noDelegateCall.sol https://github.com/Uniswap/v3-core/blob/main/contracts/NoDelegateCall.sol и нашел способ предотвратить вызов контракта из другого cotract. Когда я попытался реализовать это, я столкнулся с проблемой.

      pragma solidity >0.8.0;

contract Receiver {
    string greeting = "Hello";
    address private immutable original;
    event Greeting(string greeting, address original, address addressThis);

    constructor() {
        original = address(this);
    }

    function checkNotDelegateCall() private view {
        require(address(this) == original);
    }

    modifier noDelegateCall() {
        checkNotDelegateCall();
        _;
    }
    
    function greet() external noDelegateCall {
        emit Greeting(greeting, original, address(this));
    }
}

contract Sender {
    string greeting = "Hi";
    
    function delegatedGreeting(address _contract) external {
        (bool success,) = _contract.delegatecall(
            abi.encodeWithSignature("greet()")
        );
    }
}

Если я вызываю функцию delegatedGreeting, я ожидал, что функция будет возвращена, потому что исходная переменная и адрес (this) отличаются. Однако, хотя он генерирует пустое событие, он все равно не возвращается. Почему так происходит?

1 ответ

Когда низкоуровневый вызов делегата отменяется, он не отменяет автоматически основную транзакцию. Вместо этого он возвращает falseкак первое возвращаемое значение delegatecall()функция.

Поэтому вам нужно проверить возвращаемое значение (в вашем случае bool success) и подтвердите это.

      function delegatedGreeting(address _contract) external {
    (bool success,) = _contract.delegatecall(
        abi.encodeWithSignature("greet()")
    );
    require(success == true, "delegatecall failed");
}
Другие вопросы по тегам