← Back to list

Smart Contract Security 101: Mastering Pausable Contracts, Blacklists, and Critical Tests

🔒 In the high-stakes world of blockchain, security isn’t optional — it’s existential. Learn how to bulletproof your contracts with…

Rob DC · 2025-05-05 00:15 · 0 claps · 2.4 min read
#critical-test #smart-contracts #foundry #solidity #nearx
Open on Medium ↗
Wiki topics: CRY · Crypto & Web3 📐 · Mathematics 💭 · Philosophy of Spirit

Smart Contract Security 101: Mastering Pausable Contracts, Blacklists, and Critical Tests

🔒 In the high-stakes world of blockchain, security isn’t optional — it’s existential. Learn how to bulletproof your contracts with pausable mechanics, blacklists, and rigorous testing.

Run Critical Tests!

Run Critical Tests!

Why Security Features Like Pausable and Blacklist Matter

Imagine discovering a critical vulnerability in your live smart contract. Without a way to halt transactions, attackers could drain funds in minutes. Or picture a stolen private key — malicious actors could wreak havoc unchecked. This is where Pausable and Blacklist patterns become your first line of defense:

  • Pausable: Lets you freeze contract operations during emergencies.
  • Blacklist: Blocks specific addresses (e.g., hackers, stolen wallets) from interacting.

Let’s dissect these tools and why testing them is non-negotiable.

1. The Pausable Contract: Your Emergency Brake

A Pausable contract allows privileged accounts (like owners) to temporarily disable critical functions. Here’s a minimalist implementation:

abstract contract Pausable is Ownable {  
    bool public paused;  
    event Pause();  
    event Unpause();  

    modifier whenNotPaused() {  
        if (paused) revert("PAUSED");  
        _;  
    }  
    function pause() public onlyOwner {  
        paused = true;  
        emit Pause();  
    }  
    function unpause() public onlyOwner {  
        paused = false;  
        emit Unpause();  
    }  
}

Key Use Cases:

  • Responding to detected exploits.
  • Performing emergency maintenance.
  • Complying with legal requirements.

2. Blacklist: Banning Bad Actors

A blacklist restricts flagged addresses from executing sensitive operations. In an ERC-20 token, this could block transfers:

contract ERC20_Token is Ownable, Pausable {  
...
    mapping(address => bool) public isBlacklisted;  
...    
    event Blacklist(address indexed user);  
    event Unblacklist(address indexed user);
...  
    function blacklist(address user) public onlyOwner {  
        isBlacklisted[user] = true;  
        emit Blacklist(user);  
    }  
    function unblacklist(address user) public onlyOwner {  
        isBlacklisted[user] = false;  
        emit Unblacklist(user);  
    }  
    // Example: Integrate with transfer functions  
    function transfer(address to, uint256 amount) public whenNotPaused {  
        require(!isBlacklisted[msg.sender], "BLACKLISTED");  
        super.transfer(to, amount);  
    }  
}

Why It’s Crucial:

  • Mitigates phishing/theft impacts.
  • Enforces regulatory compliance (e.g., sanctions).

3. Testing Critical Features: Your Safety Net

Automated tests aren’t just “nice to have” — they’re your contract’s immune system. Let’s break down essential tests using Foundry:

Test 1: Pause/Unpause Mechanics

function testPause() public {  
    vm.prank(owner);  
    token.pause();  

    vm.prank(owner);  
    token.mint(100 ether);  
    // Transfers should fail when paused  
    vm.prank(owner);  
    vm.expectRevert("PAUSED");  
    token.transfer(user1, 50 ether);  
    // Resume operations  
    vm.prank(owner);  
    token.unpause();  
    vm.prank(owner);  
    token.transfer(user1, 50 ether);  
    assertEq(token.balanceOf(user1), 50 ether);  
}

Test 2: Blacklist Enforcement

function testBlacklist() public {  
    vm.prank(owner);  
    token.blacklist(user1);  
    // Blacklisted user can't transfer  
    vm.prank(user1);  
    vm.expectRevert("BLACKLISTED");  
    token.transfer(user2, 10 ether);  
    // Unblacklist and verify  
    vm.prank(owner);  
    token.unblacklist(user1);  
    vm.prank(user1);  
    token.transfer(user2, 10 ether);  
}

Test 3: Edge Cases

Don’t overlook scenarios like:

  • Insufficient balances.
  • Unauthorized mint/burn attempts.
  • Allowance exploits.
function testTransferInsufficientBalance() public {  
    vm.prank(owner);  
    token.mint(100 ether);  
    vm.prank(owner);  
    vm.expectRevert("ERC20: insufficient balance");  
    token.transfer(user1, 101 ether);  
}  

function testMintNonOwner() public {  
    vm.prank(user1); // Non-owner tries to mint  
    vm.expectRevert("NOT AUTHORIZED");  
    token.mint(100 ether);  
}

Why These Tests Save Projects

  1. Prevent Catastrophic Failures: A single bug can lose millions. Tests catch issues pre-deployment.
  2. Ensure Access Control: Verify that only authorized roles (e.g., owners) execute privileged functions.
  3. Validate State Changes: Confirm that blacklisting/pausing actually modifies contract behavior.

Final Word: Security Is a Culture

Pausable contracts and blacklists are powerful, but they’re only as strong as your testing rigor. Tools like Foundry (used in the examples) make it easier than ever to simulate attacks and edge cases.

By baking security into every layer, you’re not just writing code — you’re building trust.

Our new contrack with Blacklist validation is available at Sepolia etherscan. at 0x1949b0d792ed35dd04eb540b5571d20fb698d566.

Share your security tips or questions below. Let’s make Web3 safer, one contract at a time!

Stay secure. Build boldly. 🛡️⚡


메타데이터
post_id
d9cd72b0c500
slug
smart-contract-security-101-mastering-pausable-contracts-blacklists-and-critical-tests-d9cd72b0c500
url
https://medium.com/@pavusa/smart-contract-security-101-mastering-pausable-contracts-blacklists-and-critical-tests-d9cd72b0c500
canonical_url
https://medium.com/@pavusa/smart-contract-security-101-mastering-pausable-contracts-blacklists-and-critical-tests-d9cd72b0c500
author_url
https://medium.com/@pavusa
status
ok
fetched_at
2026-06-26 03:39:16