The audit of the contract codebase has identified the need to implement proper pausing functionality using the Pausable
pattern. This pattern allows a contract to be temporarily paused, preventing specific functions from executing. Implementing and securing the pause functionality is crucial for managing emergency situations and ensuring contract stability.
Issue: The contract is designed to be pausable, but the implementation of the pause functionality lacks proper access control and security measures.
Code Example: The setPauseStatus
function in /src/utils/Rescuable.sol
provides a way to set the pause status but does not show the implementation details of _pause()
and _unpause()
functions, or if they are correctly secured.
Location: /src/utils/Rescuable.sol
- Lines 46 - 54
Security: Without proper access control, unauthorized users could potentially pause or unpause the contract, disrupting its functionality or leading to potential misuse.
Functionality: If the pause functionality is not correctly secured, it could be exploited to prevent the contract from functioning as intended during critical operations.
Access Control: It is crucial to ensure that only the authorized owner can pause or unpause the contract to maintain control and prevent unauthorized access.
Implement Pausable Functionality: Ensure that the contract inherits from the Pausable
contract provided by OpenZeppelin. This will give access to the _pause()
and _unpause()
functions.
import "@openzeppelin/contracts/security/Pausable.sol"; contract YourContract is Pausable { // Your contract implementation }
Secure Pause Functions: Implement the pause()
and unpause()
functions and secure them with the onlyOwner
modifier to restrict access to authorized users only.
Example:
import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/security/Pausable.sol"; contract YourContract is Pausable, Ownable { function pause() external onlyOwner { _pause(); } function unpause() external onlyOwner { _unpause(); } }
Verify Access Control: Ensure that the onlyOwner
modifier is applied correctly and verify that the owner is set appropriately. This can be done by testing the access control mechanisms to prevent unauthorized actions.
Testing: Thoroughly test the pause and unpause functionality to ensure that it behaves as expected. Test cases should cover scenarios where the contract is paused and then resumed to confirm that the contract's behavior aligns with expectations.
Before:
// /src/utils/Rescuable.sol function setPauseStatus(bool pauseSatus) external onlyOwner { if (pauseSatus) { _pause(); } else { _unpause(); } emit SetPauseStatus(pauseSatus); }
After:
// /src/utils/Rescuable.sol import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/security/Pausable.sol"; contract Rescuable is Pausable, Ownable { function pause() external onlyOwner { _pause(); emit SetPauseStatus(true); } function unpause() external onlyOwner { _unpause(); emit SetPauseStatus(false); } event SetPauseStatus(bool paused); }
Implementing and securing the pausable functionality in a contract is essential for maintaining control and ensuring contract stability. By using the Pausable
pattern and securing the pause and unpause functions with the onlyOwner
modifier, you can protect the contract from unauthorized actions and ensure it remains functional during critical situations. Ensure thorough testing to validate the implementation and verify access control.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.