You are taking quiz solidityquiz.com/q/6lbz8. After 0 of 10 questions, you have 0.00 points.

Question #30 Difficulty: 3

According to the Solidity 0.8.17 compiler (200 optimization runs)

    // Which token is exploitable via the Bridge contract? 
// All, None, TokenA, TokenB, TokenC, or TokenD?

contract Bridge {
  address private underlying = 0xTokenAddress;
  mapping(uint256 => address) private balances;

  function deposit(uint256 value) external returns (uint) {
    // requires approval from msg.sender
    IERC20(underlying).safeTransferFrom(msg.sender, address(this), value);
    // record the deposit
    balances[msg.sender] += _amount;
  }

  function depositWithPermit(address target, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s, address to) external returns (uint) {
    // reverts if the signature doesn't match
    IERC20(underlying).permit(target, address(this), value, deadline, v, r, s);
    // requires approval from msg.sender
    IERC20(underlying).safeTransferFrom(target, address(this), value);
    // record the deposit
    balances[to] += _amount;
  }

  function withdraw(uint256 value) external {
    // record the withdrawal, can't be less than zero
    balances[msg.sender] -= value;
    // send the tokens to the user
    IERC20(underlying).safeTransfer(msg.sender, value);
  }
}

// Implements permit() and a non-reverting fallback
contract TokenA is ERC20 {
  function permit(address, address, uint256, uint8, bytes32, bytes32) external returns (bool) {
    require(validSignature, "invalid signature");
    return true;
  }

  fallback() external payable {
    if (msg.value > 0) {
      // send all the ether back to the sender
      payable(msg.sender).transfer(msg.value);
    }
  }
}

// Implements permit() and a reverting fallback
contract TokenB is ERC20 {
  function permit(address, address, uint256, uint8, bytes32, bytes32) external returns (bool) {
    require(validSignature, "invalid signature");
    return true;
  }

  fallback() external payable {
    if (msg.value > 0) {
      revert(false, "no ether");
    }
  }
}

// Does not implement permit() and a non-reverting fallback
contract TokenC is ERC20 {
  fallback() external payable {
    if (msg.value > 0) {
      // send all the ether back to the sender
      payable(msg.sender).transfer(msg.value);
    }
  }
}

// Does not implement permit() and a reverting fallback
contract TokenD is ERC20 {
  fallback() external payable {
    if (msg.value > 0) {
      // fail if ether is sent to this contract
      revert(false, "no ether");
    }
  }
}

Hint:

How can attacker deposit tokens on a user's behalf?

Answer:

Mode : Quiz

If you want to quit the current quiz and go back to training mode, click here.