1

我是学习 Uniswap V3 的 github 代码的新手。我想出了noDelegateCall.sol并找到了防止合同被另一个合同委托调用的方法。当我试图实现这一点时,我遇到了这个问题。

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()")
        );
    }
}

如果我调用 function delegatedGreeting,我希望函数会被还原,因为变量 original 和 address(this) 不同。但是,尽管它发出一个空事件,但它仍然不会恢复。为什么会这样?

4

1 回答 1

1

当低级委托调用恢复时,它不会自动恢复主事务。相反,它false作为delegatecall()函数的第一个返回值返回。

所以你需要检查返回值(在你的情况下bool success)并验证它。

function delegatedGreeting(address _contract) external {
    (bool success,) = _contract.delegatecall(
        abi.encodeWithSignature("greet()")
    );
    require(success == true, "delegatecall failed");
}
于 2021-12-30T12:05:48.617 回答