Security Recommendations for BNB Chain Builders
Last week, Cantina officially joined the BNB Chain Kickstart Program as a security service provider. With hundreds of thousands of developers building on the BNB Chain, security is a foundational priority for both ecosystems.
Today, in collaboration with the BNB Chain team, we are sharing a practical security guide to help developers across ecosystems adopt stronger security practices from day one. These 15 actionable recommendations are especially relevant for BNB Chain builders and are drawn from real-world incidents, recurring vulnerability patterns, and proven defenses.
BNB Chain’s low fees, rapid finality, and thriving ecosystem make it an ideal environment for innovation. But that same scale and composability demand a thoughtful approach to security from every team deploying on the network. Let’s dive in.
1. Enforce Nonce-based Signature Validation
mapping(address => mapping(uint256 => bool)) public usedNonces;
function transferWithSig(
address from,
address to,
uint256 amount,
uint256 nonce,
bytes calldata sig
) external {
require(!usedNonces[from][nonce], "Used nonce");
bytes32 hash = keccak256(abi.encodePacked(from, to, amount, nonce));
require(_verify(hash, sig, from), "Invalid sig");
usedNonces[from][nonce] = true;
_transfer(from, to, amount);
}
Avoid replayable off-chain signatures by adding nonces and validating them strictly.
This simple addition prevents transaction replays across networks or within the same chain.
2. Always Apply Checks-Effects-Interactions
function withdraw(uint amount) public {
require(balance[msg.sender] >= amount);
balance[msg.sender] -= amount;
(bool sent, ) = msg.sender.call{value: amount}("");
require(sent);
}
State changes must always precede external calls. This pattern minimizes reentrancy risk:
Cantina reviewers consistently flag reversed order logic in engagements—even minor violations can open exploit paths.
3. Avoid On-chain Oracles With Synchronous Exposure
Directly reading DEX pair reserves (e.g., Uniswap, PancakeSwap) introduces attack surfaces.
Replace synchronous reads with TWAPs or decentralized oracle networks for pricing.
4. Limit Upgrade Complexity
uint256[50] private __gap;
Use established proxy patterns and avoid inline custom modifications. Insert storage gaps or adopt EIP-7201 for structured storage namespacing.
Proxies remain a common vector for subtle logic corruption. Cantina researchers validate storage layout integrity during upgrade audits and recommend consistent use of storage management patterns to avoid overlaps and collisions.
5. Restrict Visibility and Enforce Role Control
Explicitly define external, internal, public access. Rely on onlyOwner or role-based modifiers where appropriate:
function setAdmin(address a) external onlyOwner {
admins[a] = true;
}
Visibility defaults and missing role enforcement continue to be one of the top root causes in critical incidents.
6. Use Commit-Reveal for Front-Running Resistance
For auctions, votes, and predictions, conceal sensitive input:
uint public commitDeadline;
uint public revealDeadline;
mapping(address => bytes32) public commits;
constructor(uint _commitDuration, uint _revealDuration) {
commitDeadline = block.timestamp + _commitDuration;
revealDeadline = commitDeadline + _revealDuration;
}
function commit(bytes32 hash) public {
require(block.timestamp < commitDeadline, "Commit phase ended");
commits[msg.sender] = hash;
}
function reveal(uint val, string memory salt) public {
require(block.timestamp >= commitDeadline, "Reveal phase not started");
require(block.timestamp <= revealDeadline, "Reveal phase ended");
require(commits[msg.sender] == keccak256(abi.encodePacked(val, salt)), "Invalid reveal");
_process(val);
}
Fair sequencing services can supplement this design where available.
7. Create and Maintain Incident Response Protocols
Define incident response roles, multisig controls, and emergency pause functions. Cantina offers on-demand incident command services to triage and mitigate during active exploits.
8. Integrate High-Signal Security Audits
Engage auditors with direct domain expertise in areas relevant to your protocol - whether DeFi, NFTs, L2 infrastructure, or beyond. Tailored, high-context reviews uncover issues that generic assessments may miss. Structure reviews to match system complexity, with solo or modular teams depending on the surface area and risk.
9. Host Bug Bounty Programs
Well-scoped bug bounty programs help uncover edge cases beyond the reach of traditional audits. They allow continuous review under real-world conditions by incentivizing external researchers. Successful programs include clear rules, structured triage processes, and meaningful rewards aligned with severity.
10. Sanitize and Validate All External Inputs
Guard conditions on inputs reduce unexpected edge behavior. This includes function parameters, calldata, msg.value, and token amounts.
require(userInput < threshold);
require(userAddress != address(0));
11. Handle Fallbacks and Bounces Properly
Always define receive() and fallback() explicitly. Avoid assuming all value sends will succeed. For systems with internal messaging (cross-chain, etc.), explicitly parse and verify bounced messages.
12. Test Cold Paths and Asynchronous States
Complex flows require simulation beyond unit tests. Use Foundry or Hardhat for concurrency testing. Cantina incorporates cold path fuzzing in its standard audit flow.
13. Review Token Standard Assumptions
Ensure compatibility and compliance with token standards. Do not assume all ERC20s return true on transfer() or approve().
14. Validate External Calls and Fallback Paths
Avoid unchecked low-level calls. Validate execution paths and fallback behaviors to prevent silent failures.
(bool success, bytes memory data) = someAddr. call(payload);
require (success, "Call failed");
15. Formalize Pre-Launch and Post-Launch Security Checklists
A secure protocol requires layered defenses that span the entire product lifecycle. Below is a recommended security stack combining essential tools and processes:
Pre-Deployment
- Threat Modeling: Model protocol structure and trust boundaries early.
- Expert Security Audits: Target the most critical logic and economic assumptions.
Deployment
- Bug Bounties: Incentivize discovery of issues via continuous bounty programs.
- Incident Response Playbooks: Define roles, multisig control, and communication paths for rapid action.
Runtime
- Onchain Monitoring: Alert on anomalies in transaction patterns, vaults, and governance.
- Upgrade Controls: Use time-locked, role-gated upgrades with simulation environments.
- Validator Simulation (if applicable): Test edge behaviors of validator or relayer roles.
Final thoughts
BNB Chain developers can build more resilient systems by operationalizing these practices. Cantina provides modular audit formats, a network of elite security researchers, full-scope security coverage - from first commit to incident response management, and beyond.
Ready to secure your next deployment? Let’s talk.
