Skip to content
Contract · Payments

Escrow

Two-party escrow for BNB or BNB20. Buyer deposits; arbiter can release to seller or refund buyer.

All templates
Payments
~900k gas
BNB Smart Chain
Post-deploy checklist
  1. Confirm buyer, seller, and arbiter addresses before deploy
  2. Fund the escrow after deploy (BNB or approved BNB20)
  3. Document release conditions off-chain before signing
  4. Verify on BscScan so parties can read the rules
Configure & deploy

Address that deposits funds into escrow.

Address that receives funds on release.

Trusted third party who can release or refund.

Use cases
  • OTC token sales
  • Freelance milestone payments
  • P2P marketplace settlements
SimpleEscrow.solsolidity
// SPDX-License-Identifier: MIT
// Compatible with OpenZeppelin Contracts ^5.0 (Wizard / Contracts MCP patterns)
// Compiled with Solidity ^0.8.24 — BNB Toolset browser solc
pragma solidity ^0.8.24;

import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";

contract SimpleEscrow is ReentrancyGuard {
    address public immutable buyer;
    address public immutable seller;
    address public immutable arbiter;
    uint256 public deposited;
    bool public released;
    bool public refunded;

    constructor(address _buyer, address _seller, address _arbiter) {
        require(_buyer != address(0) && _seller != address(0) && _arbiter != address(0), "zero");
        buyer = _buyer;
        seller = _seller;
        arbiter = _arbiter;
    }

    receive() external payable {
        require(msg.sender == buyer, "buyer only");
        require(!released && !refunded, "settled");
        deposited += msg.value;
    }

    function release() external nonReentrant {
        require(msg.sender == arbiter || msg.sender == buyer, "unauthorized");
        require(!released && !refunded, "settled");
        require(deposited > 0, "empty");
        released = true;
        uint256 amt = deposited;
        deposited = 0;
        (bool ok,) = seller.call{value: amt}("");
        require(ok, "transfer failed");
    }

    function refund() external nonReentrant {
        require(msg.sender == arbiter || msg.sender == seller, "unauthorized");
        require(!released && !refunded, "settled");
        require(deposited > 0, "empty");
        refunded = true;
        uint256 amt = deposited;
        deposited = 0;
        (bool ok,) = buyer.call{value: amt}("");
        require(ok, "transfer failed");
    }
}