Skip to content

Architecture ​

The contract is intentionally compact. That simplicity is useful, but it makes understanding the state machine of utmost importance.

Components ​

IERC20 ​

A minimal ERC-20 interface. The escrow contract relies on transferFrom while funding and transfer while refunding or withdrawing.

FeeLibrary ​

The library performs basis-point calculations using 10,000 as the denominator.

text
100 bps  = 1%
500 bps  = 5%
1000 bps = 10%

The constructor rejects fees above 1000 basis points.

EscrowContract ​

The principal state is:

solidity
uint256 public nextEscrowId = 1;
mapping(uint256 => Escrow) public escrows;
mapping(address => mapping(address => uint256)) public userBalances;
uint256 public platformFeeBps;
address public platformWallet;

The nested balance mapping is germane because balances are tracked per user and per token.

MockToken ​

A small mock ERC-20-style token is included in the same file for demonstration. It is not an OpenZeppelin ERC-20 implementation.

Escrow data model ​

solidity
struct Escrow {
    address client;
    address freelancer;
    uint256 amount;
    address token;
    uint256 deadline;
    Status status;
}

State model ​

text
Created
   │
   │ fundEscrow()
   ▼
Funded
  ├──────── requestRefund() after deadline ────────► Refunded
  │
  │ deliverWork()
  ▼
Delivered
   │
   │ approveWork()
   ▼
Approved

There is no implemented transition out of Approved or Refunded, and there is no refund path once the freelancer moves an escrow to Delivered.

Payment accounting ​

Approval credits internal balances first. The freelancer and platform later call withdraw() to move ERC-20 tokens from the contract to their wallets.

Documentation grounded in the current ERC-20 escrow implementation.