RACE #11 - Staking

Note: All 8 questions in this RACE are based on the below contract. This is the same contract you will see for all the 8 questions in this RACE. The question is below the shown contract.

// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";


contract Staking {

   using SafeERC20 for IERC20;

   bool internal _paused;
   address internal _operator;
   address internal _governance;
   address internal _token;
   uint256 internal _minDepositLockTime;

   mapping(address => uint256) _userBalances;
   mapping(address => uint256) _userLastDeposit;

   event Deposit(
       address indexed user,
       uint256 amount
   );

   event Withdraw(
       address indexed user,
       uint256 amount
   );

   constructor(address operator, address governance, address token, uint256 minDepositLockTime) {
       _operator = operator;
       _governance = governance;
       _token = token;
       _minDepositLockTime = minDepositLockTime;
   }

   function depositFor(address user, uint256 amount) external {
       _userBalances[user] += amount;
       _userLastDeposit[user] = block.timestamp;

       IERC20(_token).safeTransferFrom(user, address(this), amount);

       emit Deposit(msg.sender, amount);
   }

   function withdraw(uint256 amount) external {
       require(!_paused, 'paused');
       require(block.timestamp >= _userLastDeposit[msg.sender] + _minDepositLockTime, 'too early');

       IERC20(_token).safeTransferFrom(address(this), msg.sender, amount);

       if (_userBalances[msg.sender] >= amount) {
           _userBalances[msg.sender] -= amount;
       } else {
           _userBalances[msg.sender] = 0;
       }

       emit Withdraw(msg.sender, amount);
   }

   function pause() external {
       // operator or gov
       require(msg.sender == _operator && msg.sender == _governance, 'unauthorized');

       _paused = true;
   }

   function unpause() external {
       // only gov
       require(msg.sender == _governance, 'unauthorized');

       _paused = false;
   }

   function changeGovernance(address governance) external {
       _governance = governance;
   }
}

Question 1

Which statements are true in withdraw()?

Question 2

Which mitigations are applicable to withdraw()?

Question 3

The security concern(s) in pause() is/are:

Question 4

Which statement(s) is/are true for unpause()?

Question 5

Which statement(s) is/are true in depositFor()?

Question 6

The issue(s) in depositFor() is/are:

Question 7

Which of the following statement(s) is/are true?

Question 8

Potential gas optimization(s) is/are:

Last updated