Technical Architecture
Deep dive into MakaPay's smart contract architecture, deterministic addresses, and cross-chain capabilities.
Smart Contract Overview
MakaPay uses a minimal proxy pattern with CREATE2 for gas-efficient, deterministic payment addresses.
┌─────────────────────────────────────────────────────────────┐
│ MakaChain (Hub) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ GasTank │ │PaymentNotifier│ │ TrustedOracle │ │
│ │ (Balances) │ │ (Events) │ │ (Price Feeds) │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ Payment Chains (Ethereum, Polygon, BSC) │
│ ┌─────────────────────────┐ ┌───────────────────────────┐ │
│ │ PaymentWalletFactory │ │ PaymentWalletImplementation│ │
│ │ (Deploys wallets) │ │ (Template contract) │ │
│ └─────────────────────────┘ └───────────────────────────┘ │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │PaymentWallet│ │PaymentWallet│ │PaymentWallet│ ... │
│ │ (Proxy 1) │ │ (Proxy 2) │ │ (Proxy N) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘PaymentWalletFactory
The Factory contract deploys payment wallets using the CREATE2 opcode for deterministic addresses.
Key Functions
computeAddress()
computeAddress()Pre-computes the payment wallet address before deployment.
Parameters:
orderId: Unique payment identifiermerchant: Address to receive fundstoken: ERC20 token contract addressfeeRecipient: Address receiving protocol feesfeeAmount: Fee amount to deduct
Returns: The deterministic address where the wallet will be deployed.
createPaymentWallet()
createPaymentWallet()Deploys a payment wallet at the pre-computed address.
What happens:
Computes salt from all parameters
Deploys minimal proxy via CREATE2
Initializes the proxy with payment details
Automatically calls
withdraw()to settle funds
Address Computation (CREATE2)
The wallet address is computed as:
Where salt is:
PaymentWalletImplementation
The implementation contract contains the logic that all payment wallet proxies delegate to.
Storage Variables
Key Functions
initialize()
initialize()Called once when the proxy is deployed.
withdraw()
withdraw()Settles funds to the merchant.
Logic:
Get token balance of wallet
Calculate fee (proportional if partial payment)
Transfer fee to
feeRecipientTransfer remainder to
merchantCall merchant's
onPaymentReceived()callback (if contract)
EIP-1167 Minimal Proxy Pattern
Instead of deploying full contract bytecode for each payment, we use minimal proxies.
Benefits
Deployment Gas
~500,000
~50,000
Bytecode Size
~5KB
~45 bytes
Functionality
Full
Delegates to implementation
How It Works
The minimal proxy is just 45 bytes:
All calls to the proxy are delegated to the implementation contract.
Nick's Method & Cross-Chain Recovery
What is Nick's Method?
Nick's Method (named after Nick Johnson) uses CREATE2 to deploy contracts at the same address across different blockchains.
Why It Matters for MakaPay
Problem: A customer sends USDT on Polygon to an address, but the merchant expected payment on Ethereum.
Traditional Approach: Funds are lost. The address on Ethereum is either:
Empty (no contract)
A different contract
Inaccessible
MakaPay Approach: Because we use CREATE2 with identical parameters:
The address is the same on all chains
We can deploy the same wallet on any chain
Funds can be recovered by deploying on the correct chain
How Cross-Chain Recovery Works
Technical Requirements for Same Address
For the address to be identical across chains:
Same Factory Address: Factory must be at same address on all chains
Same Implementation: Implementation bytecode must be identical
Same Parameters: orderId, merchant, token address*, feeRecipient, feeAmount
*Token addresses may differ across chains, but the computation uses the original chain's token address.
Deploying Factory at Same Address
We use a keyless deployment transaction (Nick's original method):
Payment Flow (On-Chain)
Step 1: Address Computation
Step 2: Customer Payment
Step 3: Settlement
Step 4: Callback (Optional)
If merchant is a contract implementing IPaymentReceiver:
The wallet calls this after settlement, enabling:
Automatic order fulfillment
Inventory updates
Event logging
PaymentNotifier (Gasless Settlements)
For gasless payments, the PaymentNotifier records settlements on MakaChain.
Purpose
Single source of truth for all settlements
Emits events for off-chain indexing
Collects processing fee ($0.10)
Contract Interface
Event
Security Measures
Reentrancy Protection
All fund-moving functions use nonReentrant modifier:
SafeERC20
All token transfers use OpenZeppelin's SafeERC20:
One-Time Initialization
Proxies can only be initialized once:
Nonce Validation (Gas Tank)
Deposits use nonces to prevent replay attacks:
Contract Addresses
MakaChain Mainnet (777178)
GasTank
0x...
PaymentNotifier
0x...
TrustedOracle
0x...
USDT
0x30C28E393E0732335235685B345c95E6465Ad8A5
Payment Chains
Ethereum
0x...
0x...
Polygon
0x...
0x...
BSC
0x...
0x...
MakaChain
0x...
0x...
Addresses are identical across all chains due to Nick's Method deployment.
Upgradeability
Factory & Implementation
Not upgradeable by design
New versions deploy as new contracts
Existing payments continue to work
Ensures immutability and trust
GasTank
Upgradeable by owner
Emergency functions for edge cases
Multi-sig control recommended
Last updated