
Introduction: Why This Topic Demands Legal and Audit Attention
For centuries, contracts have been written in language and enforced by people.
Smart contracts change only one thing — but it is a decisive one.
They execute.
A smart contract is not an agreement waiting to be interpreted or enforced later.
It is an agreement whose performance is embedded directly into software.
Once deployed, the contract:
- does not wait for approval,
- does not rely on discretion,
- and does not pause for interpretation.
If the condition occurs, the action follows.
For lawyers, this shifts focus from post-breach enforcement to pre-deployment intent.
For auditors, it shifts focus from process compliance to design correctness.
This is not a theoretical discussion.
Smart contracts are already governing:
- ownership transfers,
- escrow arrangements,
- lending and collateral enforcement,
- subscriptions and recurring payments,
- governance decisions,
- cross-border settlements,
- and machine-to-machine commerce.
The sections that follow present simplified smart contract patterns that mirror familiar legal constructs — rewritten as executable logic.
They are deliberately compact to make intent visible, authority explicit, and enforcement unambiguous.
These examples are not production systems.
They are illustrations of how legal rules become deterministic systems.
With that framing, the examples below should be read not as programming artifacts,
but as contracts that no longer wait to be enforced.
Ganesh, below are compact “pattern” examples for each category.
These are educational snippets, not production-ready (no audits, missing edge cases, no upgrade strategy).
1) Token contract (ERC-20 style)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract SimpleERC20 {
string public name = "DemoToken";
string public symbol = "DEMO";
uint8 public decimals = 18;
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
constructor(uint256 supply) {
totalSupply = supply;
balanceOf[msg.sender] = supply;
emit Transfer(address(0), msg.sender, supply);
}
function transfer(address to, uint256 value) external returns (bool) {
require(balanceOf[msg.sender] >= value, "bal");
balanceOf[msg.sender] -= value;
balanceOf[to] += value;
emit Transfer(msg.sender, to, value);
return true;
}
function approve(address spender, uint256 value) external returns (bool) {
allowance[msg.sender][spender] = value;
emit Approval(msg.sender, spender, value);
return true;
}
function transferFrom(address from, address to, uint256 value) external returns (bool) {
require(balanceOf[from] >= value, "bal");
require(allowance[from][msg.sender] >= value, "allow");
allowance[from][msg.sender] -= value;
balanceOf[from] -= value;
balanceOf[to] += value;
emit Transfer(from, to, value);
return true;
}
}
2) DEX contract (constant-product AMM, Uniswap-like skeleton)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface IERC20 {
function transferFrom(address, address, uint256) external returns (bool);
function transfer(address, uint256) external returns (bool);
function balanceOf(address) external view returns (uint256);
}
contract MiniAMM {
IERC20 public tokenA;
IERC20 public tokenB;
uint256 public reserveA;
uint256 public reserveB;
constructor(address a, address b) {
tokenA = IERC20(a);
tokenB = IERC20(b);
}
function addLiquidity(uint256 amtA, uint256 amtB) external {
require(tokenA.transferFrom(msg.sender, address(this), amtA));
require(tokenB.transferFrom(msg.sender, address(this), amtB));
reserveA += amtA;
reserveB += amtB;
}
// x*y=k swap with 0.3% fee (rough)
function swapAForB(uint256 amtAIn) external {
require(tokenA.transferFrom(msg.sender, address(this), amtAIn));
uint256 amtInWithFee = (amtAIn * 997) / 1000;
uint256 bOut = (reserveB * amtInWithFee) / (reserveA + amtInWithFee);
require(bOut > 0 && bOut <= reserveB, "bad out");
reserveA += amtAIn;
reserveB -= bOut;
require(tokenB.transfer(msg.sender, bOut));
}
}
3) Lending contract (over-collateralized borrow/repay, tiny model)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface IERC20L {
function transferFrom(address, address, uint256) external returns (bool);
function transfer(address, uint256) external returns (bool);
}
contract SimpleLending {
IERC20L public collateralToken;
IERC20L public debtToken; // the token lent out
mapping(address => uint256) public collateral;
mapping(address => uint256) public debt;
uint256 public constant LTV_BPS = 5000; // 50%
constructor(address c, address d) {
collateralToken = IERC20L(c);
debtToken = IERC20L(d);
}
function depositCollateral(uint256 amount) external {
require(collateralToken.transferFrom(msg.sender, address(this), amount));
collateral[msg.sender] += amount;
}
function borrow(uint256 amount) external {
// toy: assumes 1:1 price. Real protocols use price oracles.
uint256 maxBorrow = (collateral[msg.sender] * LTV_BPS) / 10000;
require(debt[msg.sender] + amount <= maxBorrow, "ltv");
debt[msg.sender] += amount;
require(debtToken.transfer(msg.sender, amount));
}
function repay(uint256 amount) external {
require(debtToken.transferFrom(msg.sender, address(this), amount));
require(debt[msg.sender] >= amount, "too much");
debt[msg.sender] -= amount;
}
}
4) Escrow contract (milestone / deliverable release)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract Escrow {
address public payer;
address public payee;
constructor(address _payee) payable {
payer = msg.sender;
payee = _payee;
}
function release() external {
require(msg.sender == payer, "only payer"); // or add arbiter logic
payable(payee).transfer(address(this).balance);
}
function refund() external {
require(msg.sender == payee, "only payee");
payable(payer).transfer(address(this).balance);
}
}
5) NFT contract (ERC-721 style minimal)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract SimpleNFT {
string public name = "DemoNFT";
string public symbol = "DNFT";
mapping(uint256 => address) public ownerOf;
mapping(address => uint256) public balanceOf;
mapping(uint256 => address) public getApproved;
event Transfer(address indexed from, address indexed to, uint256 indexed id);
event Approval(address indexed owner, address indexed spender, uint256 indexed id);
function mint(uint256 id) external {
require(ownerOf[id] == address(0), "exists");
ownerOf[id] = msg.sender;
balanceOf[msg.sender] += 1;
emit Transfer(address(0), msg.sender, id);
}
function approve(address spender, uint256 id) external {
require(ownerOf[id] == msg.sender, "not owner");
getApproved[id] = spender;
emit Approval(msg.sender, spender, id);
}
function transferFrom(address from, address to, uint256 id) external {
require(ownerOf[id] == from, "from");
require(msg.sender == from || msg.sender == getApproved[id], "no auth");
ownerOf[id] = to;
balanceOf[from] -= 1;
balanceOf[to] += 1;
getApproved[id] = address(0);
emit Transfer(from, to, id);
}
}
6) DAO governance contract (proposal + vote + execute)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract MiniDAO {
struct Proposal {
address target;
bytes data;
uint256 yes;
uint256 no;
uint256 deadline;
bool executed;
}
mapping(uint256 => Proposal) public proposals;
mapping(uint256 => mapping(address => bool)) public voted;
uint256 public nextId;
function propose(address target, bytes calldata data, uint256 durationSec) external returns (uint256) {
uint256 id = nextId++;
proposals[id] = Proposal(target, data, 0, 0, block.timestamp + durationSec, false);
return id;
}
function vote(uint256 id, bool support) external {
Proposal storage p = proposals[id];
require(block.timestamp < p.deadline, "ended");
require(!voted[id][msg.sender], "voted");
voted[id][msg.sender] = true;
if (support) p.yes++; else p.no++;
}
function execute(uint256 id) external {
Proposal storage p = proposals[id];
require(block.timestamp >= p.deadline, "not yet");
require(!p.executed, "done");
require(p.yes > p.no, "failed");
p.executed = true;
(bool ok,) = p.target.call(p.data);
require(ok, "call failed");
}
}
7) Time-locked contract (vesting / cliff release)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract TimeLock {
address public beneficiary;
uint256 public unlockTime;
constructor(address _beneficiary, uint256 _unlockTime) payable {
beneficiary = _beneficiary;
unlockTime = _unlockTime;
}
function withdraw() external {
require(block.timestamp >= unlockTime, "locked");
require(msg.sender == beneficiary, "not beneficiary");
payable(beneficiary).transfer(address(this).balance);
}
}
8) Subscription / streaming payments (simple “drip”)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract Stream {
address public payer;
address public payee;
uint256 public ratePerSecond; // wei/sec
uint256 public start;
uint256 public withdrawn;
constructor(address _payee, uint256 _ratePerSecond) payable {
payer = msg.sender;
payee = _payee;
ratePerSecond = _ratePerSecond;
start = block.timestamp;
}
function withdraw() external {
require(msg.sender == payee, "only payee");
uint256 earned = (block.timestamp - start) * ratePerSecond;
uint256 available = earned - withdrawn;
uint256 bal = address(this).balance;
if (available > bal) available = bal;
withdrawn += available;
payable(payee).transfer(available);
}
}
9) Cross-border settlement contract (atomic delivery-vs-payment idea)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface IERC20S { function transferFrom(address,address,uint256) external returns(bool); function transfer(address,uint256) external returns(bool); }
contract AtomicDvP {
// Buyer pays token; seller releases "asset" represented by another token.
IERC20S public payToken;
IERC20S public assetToken;
constructor(address _payToken, address _assetToken) {
payToken = IERC20S(_payToken);
assetToken = IERC20S(_assetToken);
}
function settle(address buyer, address seller, uint256 payAmt, uint256 assetAmt) external {
// In practice add signatures/permissions; here it's illustrative.
require(payToken.transferFrom(buyer, seller, payAmt));
require(assetToken.transferFrom(seller, buyer, assetAmt));
}
}
10) Oracle-driven conditional contract (price trigger)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface IPriceOracle { function latestPrice() external view returns (int256); }
contract PriceTriggeredPayout {
IPriceOracle public oracle;
address public beneficiary;
int256 public threshold;
constructor(address _oracle, address _beneficiary, int256 _threshold) payable {
oracle = IPriceOracle(_oracle);
beneficiary = _beneficiary;
threshold = _threshold;
}
function claimIfAbove() external {
require(oracle.latestPrice() >= threshold, "below threshold");
payable(beneficiary).transfer(address(this).balance);
}
}
11) M2M payment contract (usage metering → pay per unit)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface IERC20M { function transferFrom(address,address,uint256) external returns(bool); }
contract PayPerKWh {
IERC20M public token; // “machine money”
address public station; // charger operator
uint256 public pricePerWh; // token units per Wh
mapping(bytes32 => uint256) public energyWh; // sessionId -> Wh delivered
constructor(address _token, address _station, uint256 _pricePerWh) {
token = IERC20M(_token);
station = _station;
pricePerWh = _pricePerWh;
}
// Called by metering system (in reality: signed data / oracle / secure meter)
function recordEnergy(bytes32 sessionId, uint256 whDelivered) external {
require(msg.sender == station, "only station");
energyWh[sessionId] += whDelivered;
}
function settle(bytes32 sessionId, address vehicle) external {
uint256 cost = energyWh[sessionId] * pricePerWh;
energyWh[sessionId] = 0;
require(token.transferFrom(vehicle, station, cost));
}
}


Leave a comment