Analise smart-contract
03.04.2024

Smart contracts with Pause function

We continue the series of articles devoted to the description of fraudulent schemes in smart contracts. Today we will analyze smart contracts with Pause function.

Smart contracts with Pause features provide the ability to temporarily or permanently stop certain operations or functions within the contract. While Pause features can be useful for security and maintenance, they also pose a potential risk if they are used by fraudsters. To protect yourself and identify potential threats, you need to understand the risks, common fraud schemes, and how to recognize them in a smart contract.

The dangers of smart contracts with the Pause feature:

  • Unauthorized Pause: Fraudsters can gain control of the Pause feature and stop the contract without proper authorization, which can result in business disruption or financial loss.

  • Deceptive Delays: Malicious contracts may suspend critical transactions, such as withdrawals or transfers, under the guise of temporary maintenance or security measures, with the intent of denying users access to their assets.

  • False claims of emergencies: Fraudsters may falsely claim emergencies or vulnerabilities to justify a contract suspension and then use users' funds during the pause.

  • Security Pretext: Malicious contracts may claim that a security vulnerability has been discovered, resulting in the activation of the suspend function. In reality, fraudsters may intend to take advantage of the situation.

  • Emergency Schemes: Fraudsters may use fear-inducing language or scenarios, such as claiming a "burglary attempt" or "emergency situation" to justify a pause during which they may commit illegal acts.

How can you independently determine if such threats are present in smart contracts?

If you want to determine the presence of Pause functions in smart contracts on your own, the following tips will be helpful in doing so.

  1. Examine the source code of the contract to see if there is a Pause feature. Ensure that the pause mechanism is well documented and has appropriate access controls.

  2. Find out who controls the Pause function. Unauthorized or unchecked possession of the Pause function is a potential problem.

  3. Read the documentation and project specifications to ensure that they provide clear and accurate information about the Pause function, its purpose, and the circumstances under which it may be used.

  4. Check the Transparency of the use of the Pause function. Ensure that there are clear procedures for managing and deciding whether to activate or deactivate Pause.

  5. Pay attention to external audits of smart contract security, especially the Pause mechanism. Auditors should evaluate the security and transparency of the Pause feature.

  6. Observe the behavior of the contract and ensure that the Pause function is only activated under legitimate circumstances, such as maintenance or safety reasons.

  7. Engage with the project community and other users to understand their experiences and concerns about using the Pause feature.

  8. Keep up to date with the latest developments in our community (Telegram channel) and best practices for fraud detection (our Blog and YouTube channel).

To detect potentially malicious functionality in a Pause smart contract, you must perform due diligence, scrutinizing the code and documentation of the project. Avoid contracts with suspicious behavior or lack of transparency regarding the use of the Pause feature.

Lotus Market's security scanner finds all common (including hidden) Pause features 99.9% of the time. Use our premium subscription and protect your funds from threats.

Next, we'll look at a few of the most common examples of the Pause feature that the Lotus Market Platform successfully finds.

independently determine

Example 1: Basic Pause function


    contract BasicPauseToken {
        address public owner;
        bool public paused;
    
        constructor() {
            owner = msg.sender;
            paused = false;
        }
    
        modifier whenNotPaused() {
            require(!paused, "Contract is paused");
            _;
        }
    
        function pause() public {
            require(msg.sender == owner, "Only the owner can pause");
            paused = true;
        }
    
        function unpause() public {
            require(msg.sender == owner, "Only the owner can unpause");
            paused = false;
        }
    
        function transfer(address to, uint256 amount) public whenNotPaused {
            // Transfer logic when the contract is not paused
        }
    }

Tips for identifying: Look for a contract with functions like pause and unpause or similar functions that can toggle the pause state.

Check for a whenNotPaused type modifier applied to certain functions to ensure that they can only be executed when the contract is not suspended.

Check the access control mechanism, which should allow only the owner or authorized persons to suspend and revoke the suspension of a contract.

Example 2: Time-activated pause


    contract TimeActivatedPauseToken {
        address public owner;
        bool public paused;
        uint256 public pauseStartTime;
        uint256 public pauseDuration;
    
        constructor(uint256 _duration) {
            owner = msg.sender;
            paused = false;
            pauseStartTime = 0;
            pauseDuration = _duration;
        }
    
        modifier whenNotPaused() {
            require(!paused, "Contract is paused");
            _;
        }
    
        function pause() public {
            require(msg.sender == owner, "Only the owner can pause");
            paused = true;
            pauseStartTime = block.timestamp;
        }
    
        function unpause() public {
            require(msg.sender == owner, "Only the owner can unpause");
            require(block.timestamp >= pauseStartTime + pauseDuration, "Pause duration not over");
            paused = false;
        }
    
        function transfer(address to, uint256 amount) public whenNotPaused {
            // Transfer logic when the contract is not paused
        }
    }

Tips for identifying: Look for a contract with a time-activated pause mechanism in which the pause and pause cancel have a specific duration.

Check if there is a modifier of type whenNotPaused applied to certain functions. Make sure that the contract enforces the duration of the pause and allows it to be canceled only after the specified period of time has elapsed.

When identifying Pause features in a smart contract, it is critical to examine the code, access controls, and purpose of the pause mechanism. Carefully review the documentation and contract management model, and engage with the project community to assess the legitimacy of the contract and whether it is fit for purpose. Always exercise caution and conduct due diligence before engaging in any transaction or investment involving suspendable contracts.

time-activated pause

Example 3: Conditional pause function


    contract ConditionalPauseToken {
        address public owner;
        bool public paused;
    
        constructor() {
            owner = msg.sender;
            paused = false;
        }
    
        modifier whenNotPaused() {
            require(!paused || msg.sender == owner, "Contract is paused");
            _;
        }
    
        function pause() public {
            require(msg.sender == owner, "Only the owner can pause");
            paused = true;
        }
    
        function unpause() public {
            require(msg.sender == owner, "Only the owner can unpause");
            paused = false;
        }
    
        function transfer(address to, uint256 amount) public whenNotPaused {
            // Transfer logic when the contract is not paused, except for the owner
        }
    }

Tips for identifying: Look for a contract with a conditional pause mechanism that allows the owner to perform certain transactions even if the contract is suspended.

Check if the whenNotPaused type modifier applies to functions that require the contract to be in a non-paused state.

Example 4: Emergency pause function


    contract EmergencyPauseToken {
        address public owner;
        bool public paused;
    
        constructor() {
            owner = msg.sender;
            paused = false;
        }
    
        modifier whenNotPaused() {
            require(!paused || msg.sender == owner, "Contract is paused");
            _;
        }
    
        function pause() public {
            require(msg.sender == owner, "Only the owner can pause");
            paused = true;
        }
    
        function emergencyPause() public {
            require(msg.sender == owner, "Only the owner can initiate emergency pause");
            paused = true;
        }
    
        function unpause() public {
            require(msg.sender == owner, "Only the owner can unpause");
            paused = false;
        }
    
        function transfer(address to, uint256 amount) public whenNotPaused {
            // Transfer logic when the contract is not paused, except for the owner
        }
    }

Tips for identifying: Look for a contract with an emergency pause feature that allows the owner to immediately suspend the contract even without standard suspension procedures.

Check for a modifier of type whenNotPaused to determine which operations are restricted when the contract is suspended.

Pay attention to the contract's emergency pause features and ensure that their use is tightly controlled and well documented.

Match the contract's suspension functions to its governance model and decision-making processes for activating and deactivating the suspension function.

Example 5: Owner-controlled pause with time limit


    contract TimedPauseToken {
        address public owner;
        bool public paused;
        uint256 public pauseStartTime;
        uint256 public pauseDuration;
    
        constructor(uint256 _duration) {
            owner = msg.sender;
            paused = false;
            pauseStartTime = 0;
            pauseDuration = _duration;
        }
    
        modifier whenNotPaused() {
            require(!paused, "Contract is paused");
            _;
        }
    
        function pause() public {
            require(msg.sender == owner, "Only the owner can pause");
            paused = true;
            pauseStartTime = block.timestamp;
        }
    
        function unpause() public {
            require(msg.sender == owner, "Only the owner can unpause");
            require(block.timestamp >= pauseStartTime + pauseDuration, "Pause duration not over");
            paused = false;
        }
    
        function transfer(address to, uint256 amount) public whenNotPaused {
            // Transfer logic when the contract is not paused
        }
    }

Tips for identifying: Look for a contract with an owner-controlled pause that includes a specific duration of pause and cancel pause.

Check for a modifier of type whenNotPaused applied to the appropriate functions to restrict operations when the contract is suspended.

owner-controlled pause with time limit

Example 6: Third party pause with time limit


    contract ThirdPartyTimedPauseToken {
        address public owner;
        address public thirdParty;
        bool public paused;
        uint256 public pauseStartTime;
        uint256 public pauseDuration;
    
        constructor(address _thirdParty, uint256 _duration) {
            owner = msg.sender;
            thirdParty = _thirdParty;
            paused = false;
            pauseStartTime = 0;
            pauseDuration = _duration;
        }
    
        modifier whenNotPaused() {
            require(!paused || msg.sender == owner || msg.sender == thirdParty, "Contract is paused");
            _;
        }
    
        function pause() public {
            require(msg.sender == thirdParty, "Only the third party can pause");
            paused = true;
            pauseStartTime = block.timestamp;
        }
    
        function unpause() public {
            require(msg.sender == thirdParty, "Only the third party can unpause");
            require(block.timestamp >= pauseStartTime + pauseDuration, "Pause duration not over");
            paused = false;
        }
    
        function transfer(address to, uint256 amount) public whenNotPaused {
            // Transfer logic when the contract is not paused, except for the owner and the third party
        }
    }

Tips for identifying: Look for a contract with a third-party managed suspension mechanism where the third party can suspend and disconnect the contract with a set duration.

Check for a modifier of type whenNotPaused to determine which operations are restricted when a contract is suspended.

Ensure that access control mechanisms for Pause features in the contract, whether owner-owned, community-managed or third-party, are transparent and well-designed.

When a Pause function is identified in a smart contract, a thorough code analysis should be performed, access controls should be tested, and the purpose and control model of the pause mechanism should be understood. It is critical to conduct due diligence and engage with the project community to assess the legitimacy of the contract and whether it is fit for purpose. Always exercise caution and conduct proper research before entering into contracts that offer a pause option to mitigate potential risks.

 

We hope these examples have helped you better understand the schematics of the Pause function in smart contracts.

 

Since all information in the blockchain is open (provided, of course, that the source code of the contract is verified), armed with this knowledge you can independently study smart contracts and identify various scam schemes.

However, we've already done it all for you! Sign up for a premium subscription and get access to exclusive filters on smart contracts features and fresh analytics. Increase your chances of successfully investing in profitable tokens.

Regards, Lotus Market team.

All posts

Connect to a wallet

Metamask