Cover photo

26. DoubleEntryPoint

Difficulty: 4/10

Level: https://ethernaut.openzeppelin.com/level/0x128BA32Ec698610f2fF8f010A7b74f9985a6D17c

先看通关介绍:

该合约具有 Forta 合约,任何用户都可以在其中注册自己的检测机器人合约。 Forta 是一个去中心化的、基于社区的监控网络,用于尽快检测 DeFi、NFT、治理、桥梁和其他 Web3 系统上的威胁和异常。您的工作是实施检测机器人并将其注册到 Forta 合同中。机器人的实施将需要发出正确的警报,以防止潜在的攻击或漏洞利用。

按 Get new instance 开始闯关。MetaMask 会弹出交易请求,确认以部署关卡合约,关卡正式开始。

创建 Bot 合约

  1. 打开 Remix IDE: https://remix.ethereum.org/ 创建 workspace。

  2. 新建 Bot.sol 文件

  3. 拷贝代码到 Bot.sol

    pragma solidity 0.8.7;
    
    interface IDetectionBot {
        function handleTransaction(address user, bytes calldata msgData) external;
    }
    
    interface IForta {
        function setDetectionBot(address detectionBotAddress) external;
        function notify(address user, bytes calldata msgData) external;
        function raiseAlert(address user) external;
    }
    
    contract Bot is IDetectionBot {
    
        address fortaContract = 0xD386F824FabC0bB1e85a2AD1D24642C9BaAa231A; // 通过 await contract.forta() 获得
    
        function handleTransaction(address user, bytes calldata msgData) override external {
            require(msg.sender == fortaContract);
            IForta(fortaContract).raiseAlert(user);
        }
    
    }
    
  4. 编译,部署。

    1. Solidity compiler 中选择 Compile Bot.sol

    2. DEPLOY & RUN TRANSACTIONSENVIRONMENT 中选择 Injected Web3 ,选择 CONTRACTBot.sol

    3. 部署完成后,会在下方显示 Deployed Contracts

交互 Forta 合约

  1. 新建 Forta.sol 文件

  2. 拷贝代码到 Forta.sol

    pragma solidity 0.8.7;
    
    interface IDetectionBot {
        function handleTransaction(address user, bytes calldata msgData) external;
    }
    
    interface IForta {
        function setDetectionBot(address detectionBotAddress) external;
        function notify(address user, bytes calldata msgData) external;
        function raiseAlert(address user) external;
    }
    
    contract Forta is IForta {
      mapping(address => IDetectionBot) public usersDetectionBots;
      mapping(address => uint256) public botRaisedAlerts;
    
      function setDetectionBot(address detectionBotAddress) external override {
          require(address(usersDetectionBots[msg.sender]) == address(0), "DetectionBot already set");
          usersDetectionBots[msg.sender] = IDetectionBot(detectionBotAddress);
      }
    
      function notify(address user, bytes calldata msgData) external override {
        if(address(usersDetectionBots[user]) == address(0)) return;
        try usersDetectionBots[user].handleTransaction(user, msgData) {
            return;
        } catch {}
      }
    
      function raiseAlert(address user) external override {
          if(address(usersDetectionBots[user]) != msg.sender) return;
          botRaisedAlerts[msg.sender] += 1;
      } 
    }
    
  3. 编译 Forta.sol

  4. DEPLOY & RUN TRANSACTIONSCONTRACT 选择 Forta.sol ;在 At Address 中填入 0xD386F824FabC0bB1e85a2AD1D24642C9BaAa231A ;展开下方的 Deployed Contracts

post image
  1. 点开 setDetectionBot ,传入上一步部署 bot 合约的地址,点击 transct

post image

点击提交,本关完成。