Inspiration

Over 63 million MSMEs in India alone have more than ₹10 Lakh Crore locked in unpaid B2B invoices at any given time. When a small supplier delivers goods to a corporate giant, they're forced into Net-90 day payment terms — and traditional banks reject 80% of their loan applications. Legacy factoring companies charge predatory 15%+ fees with mountains of paperwork.

I asked myself: what if an MSME could tokenise a verified invoice and receive funding from a global investor in under 60 seconds — with no bank, no middleman, and no paperwork?

That's FactorFi.


What It Does

FactorFi is a decentralised invoice factoring protocol that bridges Web2 financial truth with Web3 liquidity:

  • Sellers verify a real Stripe invoice and mint it as an ERC-721 NFT on Ethereum
  • Investors browse a marketplace of verified invoices and fund them at a seller-controlled discount in USDC
  • Buyers repay the face value into a trustless smart contract escrow
  • Investors claim their yield after repayment — all on-chain, all verifiable

The protocol charges a transparent 1% fee (hardcoded in the smart contract), and the seller controls their own discount rate via a slider (2–15%).


How I Built It

Frontend: React 19 + TypeScript + Tailwind CSS v4 + Ethers.js v6, deployed on Vercel.

Backend: A Node.js/Express proxy server (deployed on Railway) that handles all sensitive API calls server-side. The frontend never touches a single secret key.

Smart Contract: InvoiceEscrow.sol — built with Solidity ^0.8.20, OpenZeppelin (ERC721URIStorage, SafeERC20, ReentrancyGuard), deployed on Polygon Amoy Testnet.

Integrations:

  • Stripe API — Server-side invoice verification (checks existence, ownership, and open status)
  • Pinata — IPFS pinning for immutable NFT metadata
  • Resend — Automated email notifications to buyers when their invoice is funded

Challenges I Ran Into

The Oracle Problem: How do you verify that a real-world invoice exists without trusting the seller? I solved this for V1 by building a direct Stripe API bridge — the backend verifies the invoice is real and unpaid before allowing tokenisation.

Double-Financing Prevention: A malicious seller could try to mint the same invoice twice. I solved this by hashing the Web2 invoice ID on-chain in a processedInvoices mapping — the smart contract mathematically prevents duplicate minting.

RPC Performance: Naively fetching invoices with unbounded loops took 15+ seconds. I implemented a getNextTokenId() getter in the contract and used Promise.all() on the frontend, dropping load times to under 1 second.

Security without Complexity: I needed to keep Stripe/Pinata keys hidden from the client without overengineering the architecture. The Express proxy pattern gave me bank-grade key isolation with minimal overhead.


Accomplishments That I'm Proud Of

  • End-to-end working protocol — Not a mockup. Every transaction (mint, fund, repay, claim) executes on a live Ethereum testnet smart contract.
  • Trustless two-step escrow — Buyers repay into the contract, investors claim separately. No party has to trust the other.
  • Zero secret key exposure — The entire Stripe/Pinata/Resend integration runs through a secured backend proxy. The React frontend never sees a single API key.
  • Sub-second marketplace loading — Bounded RPC fetching with Promise.all() brought page load from 15s down to under 1s.
  • Anti-fraud by default — Double-financing is impossible at the smart contract level, not just the UI level.

What I Learned

  • How to architect a full-stack Web3 application with proper separation of concerns
  • The real-world challenges of RWA (Real World Asset) tokenisation — especially around fraud prevention and oracle design
  • How to build a trustless two-step escrow mechanism (repay → claim) that eliminates counterparty risk
  • The importance of bounded on-chain data fetching for frontend performance

What's Next for FactorFi

Milestone Description
Chainlink Oracle Automate repayment by listening to bank webhooks
GSTN API Verify invoices against India's government tax portal for zero-fraud origination
The Graph Replace RPC loops with indexed GraphQL queries
UUPS Proxy Make the contract upgradeable for production deployment

Built With

Share this project:

Updates