XMBL Tokenizer tokenizes everything. Loans, insurance, rwa, portfolios, etc
XMBL Tokenizer is an agentic DeFi platform that turns illiquid Real-World Assets (RWAs) into composable, tradeable financial instruments. By combining on-chain appraisal, fractionalization, and gas-free trading, we unlock liquidity for assets that were previously stagnant.
The protocol transforms a $500k house or a $50k invoice into a liquid Loan Token, which can then be traded instantly via state channels or bundled into AI-managed portfolios.
We have deeply integrated three key technologies to power this infrastructure.
Integration: Arc is the backbone of our credit and settlement system. We utilize Arc's secure, unparalleled infrastructure for processing compliant RWA transactions and USDC-denominated settlement.
LoanFactory contract ensures that when a loan is funded, the principal is transferred securely to the borrower, and the RWA NFT is locked as collateral.createLoan (locking RWA, issuing Loan Tokens) and repayLoan (unlocking collateral). It is designed to work natively with Arc's USDC and security standards.valuationUSD, documentHash, and appraiser identity, ensuring all assets meeting Arc's compliance standards.Integration: We solved the issue of liquidity fragmentation and high gas costs for trading fractionalized loan tokens by integrating the Yellow Network.
YellowBridge. This enables them to trade off-chain via state channels with zero gas fees and instant finality.startSession and utilizes cryptographic signatures to settleSession, releasing funds back to the user based on their final trading balance.Integration: To ensure our loan markets are accessible to liquidity from any chain, we embedded the LI.FI Ecosystem.
LiFiWidget configuration. We customized the theme (Obsidian/Cyber-Cyan) to blend perfectly with our app's aesthetic while retaining full bridging functionality.AssetTokenizer.sol.LoanFactory.sol locks your NFT and mints you $100k Loan Tokens.Loan Tokens into the YellowBridge.xmbl-tokenizer/
โโโ contracts/
โ โโโ core/
โ โ โโโ AssetTokenizer.sol # RWA NFT Logic
โ โ โโโ LoanFactory.sol # Loan Logic (Arc Integration)
โ โโโ integrations/
โ โ โโโ YellowBridge.sol # Yellow Network Bridge
โโโ frontend/
โ โโโ src/
โ โ โโโ components/
โ โ โ โโโ YellowTrader.tsx # Yellow Trading UI
โ โ โ โโโ LoanCreator.tsx # Loan Mgmt UI
โ โ โโโ hooks/
โ โ โ โโโ useYellowNetwork.ts # Yellow Logic
โ โ โโโ pages/
โ โ โ โโโ Bridge.tsx # LI.FI Integration
Building a meta-tokenization platform for collateralized loans, real-world assets (RWAs), and credit default swaps (CDS) with AI-powered agent strategies. Everything is tokenizable and composable into portfolio tokens through elegant recursion.
Target Prize: Best Agentic Commerce App Powered by Real-World Assets on Arc ($2,500)
Why: Perfect alignment with RWA tokenization, USDC-denominated credit, and AI agent treasury management.
Integration Points:
Target Prize: Integrate Yellow SDK - Trading Apps/Prediction Markets/Marketplaces (1st place $5,000)
Why: State channels enable gas-free trading of loan tokens, portfolio tokens, and CDS positions without blockchain friction.
Integration Points:
Target Prize: Best AI x LI.FI Smart App ($2,000) + Best Use of LI.FI Composer ($2,500)
Why: Cross-chain liquidity enables multi-chain collateral and RWA tokenization across ecosystems.
Integration Points:
contracts/
โโโ core/
โ โโโ AssetTokenizer.sol # Base ERC-721 for RWAs
โ โโโ LoanFactory.sol # Creates collateralized loans
โ โโโ LoanToken.sol # ERC-20 representing loan positions
โ โโโ InsurancePool.sol # CDS coverage pool
โ โโโ InsuranceToken.sol # ERC-20 for insurance positions
โ โโโ PortfolioToken.sol # ERC-20 wrapping multiple tokens
โ โโโ LiquidityPool.sol # Provide/withdraw liquidity
โโโ exchange/
โ โโโ OrderBook.sol # On-chain fallback orderbook
โ โโโ YellowBridge.sol # Yellow Network settlement contract
โโโ agents/
โ โโโ AgentRegistry.sol # Register AI agents
โ โโโ AgentExecutor.sol # Execute agent strategies
โ โโโ StrategyVault.sol # Agent-controlled vaults
โโโ integrations/
โโโ ArcBridge.sol # Arc Network integration
โโโ LiFiBridge.sol # LI.FI cross-chain routing
# Initialize project
mkdir defi-tokenizer-platform
cd defi-tokenizer-platform
npm init -y
# Install dependencies
npm install --save-dev hardhat @nomicfoundation/hardhat-toolbox
npm install @openzeppelin/contracts @openzeppelin/contracts-upgradeable
npm install dotenv ethers@^6
# Yellow Network SDK
npm install @yellow-network/sdk
# LI.FI SDK
npm install @lifi/sdk @lifi/widget
# Arc SDK (check docs for exact package)
# npm install @circle/arc-sdk
# Testing & deployment
npm install --save-dev chai mocha hardhat-gas-reporter solidity-coverage
npm install --save-dev @nomiclabs/hardhat-etherscan
# Initialize Hardhat
npx hardhat init
hardhat.config.js:
require("@nomicfoundation/hardhat-toolbox");
require("dotenv").config();
module.exports = {
solidity: {
version: "0.8.20",
settings: {
optimizer: {
enabled: true,
runs: 200
}
}
},
networks: {
// Arc Testnet
arcTestnet: {
url: process.env.ARC_TESTNET_RPC,
accounts: [process.env.PRIVATE_KEY],
chainId: /* Arc testnet chain ID */
},
// Additional testnets for LI.FI cross-chain
sepolia: {
url: process.env.SEPOLIA_RPC,
accounts: [process.env.PRIVATE_KEY],
chainId: 11155111
},
polygonMumbai: {
url: process.env.MUMBAI_RPC,
accounts: [process.env.PRIVATE_KEY],
chainId: 80001
}
},
gasReporter: {
enabled: true,
currency: "USD"
}
};
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
/**
* @title AssetTokenizer
* @dev Base NFT for real-world assets with metadata
*/
contract AssetTokenizer is ERC721, Ownable {
struct Asset {
string assetType; // "real_estate", "invoice", "equipment"
uint256 valuationUSD; // Appraised value
string documentHash; // IPFS hash of documentation
address appraiser; // Who valued this
uint256 createdAt;
bool isActive;
}
uint256 private _tokenIdCounter;
mapping(uint256 => Asset) public assets;
event AssetTokenized(uint256 indexed tokenId, address indexed owner, string assetType, uint256 valuation);
constructor() ERC721("RWA Token", "RWA") Ownable(msg.sender) {}
function tokenizeAsset(
string memory assetType,
uint256 valuationUSD,
string memory documentHash,
address appraiser
) external returns (uint256) {
uint256 tokenId = _tokenIdCounter++;
assets[tokenId] = Asset({
assetType: assetType,
valuationUSD: valuationUSD,
documentHash: documentHash,
appraiser: appraiser,
createdAt: block.timestamp,
isActive: true
});
_safeMint(msg.sender, tokenId);
emit AssetTokenized(tokenId, msg.sender, assetType, valuationUSD);
return tokenId;
}
function getAsset(uint256 tokenId) external view returns (Asset memory) {
require(_ownerOf(tokenId) != address(0), "Asset does not exist");
return assets[tokenId];
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
/**
* @title LoanToken
* @dev ERC-20 representing fractional loan positions
*/
contract LoanToken is ERC20 {
address public loanContract;
uint256 public loanId;
constructor(
string memory name,
string memory symbol,
uint256 _loanId,
uint256 totalSupply
) ERC20(name, symbol) {
loanContract = msg.sender;
loanId = _loanId;
_mint(msg.sender, totalSupply);
}
function getLoanInfo() external view returns (address, uint256) {
return (loanContract, loanId);
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "./LoanToken.sol";
import "./AssetTokenizer.sol";
/**
* @title LoanFactory
* @dev Creates collateralized loans settled in USDC on Arc
*/
contract LoanFactory is ReentrancyGuard {
struct Loan {
uint256 id;
address borrower;
uint256 collateralTokenId; // RWA NFT
uint256 principalUSDC;
uint256 interestRate; // Basis points (e.g., 500 = 5%)
uint256 duration; // Seconds
uint256 startTime;
uint256 totalOwed;
address loanToken; // ERC-20 for this loan
LoanStatus status;
}
enum LoanStatus { Active, Repaid, Defaulted }
IERC20 public immutable USDC;
AssetTokenizer public immutable assetTokenizer;
uint256 private _loanIdCounter;
mapping(uint256 => Loan) public loans;
mapping(address => uint256[]) public borrowerLoans;
event LoanCreated(uint256 indexed loanId, address indexed borrower, uint256 principal);
event LoanRepaid(uint256 indexed loanId, uint256 amountPaid);
event LoanDefaulted(uint256 indexed loanId);
constructor(address _usdc, address _assetTokenizer) {
USDC = IERC20(_usdc);
assetTokenizer = AssetTokenizer(_assetTokenizer);
}
function createLoan(
uint256 collateralTokenId,
uint256 principalUSDC,
uint256 interestRate,
uint256 duration
) external nonReentrant returns (uint256) {
require(assetTokenizer.ownerOf(collateralTokenId) == msg.sender, "Not collateral owner");
require(principalUSDC > 0, "Invalid principal");
uint256 loanId = _loanIdCounter++;
uint256 totalOwed = principalUSDC + (principalUSDC * interestRate / 10000);
// Transfer collateral to this contract
assetTokenizer.transferFrom(msg.sender, address(this), collateralTokenId);
// Deploy loan token (ERC-20 for trading)
LoanToken loanToken = new LoanToken(
string(abi.encodePacked("Loan #", toString(loanId))),
string(abi.encodePacked("LOAN", toString(loanId))),
loanId,
totalOwed * 1e18 // 18 decimals
);
loans[loanId] = Loan({
id: loanId,
borrower: msg.sender,
collateralTokenId: collateralTokenId,
principalUSDC: principalUSDC,
interestRate: interestRate,
duration: duration,
startTime: block.timestamp,
totalOwed: totalOwed,
loanToken: address(loanToken),
status: LoanStatus.Active
});
borrowerLoans[msg.sender].push(loanId);
// Transfer USDC to borrower
USDC.transfer(msg.sender, principalUSDC);
emit LoanCreated(loanId, msg.sender, principalUSDC);
return loanId;
}
function repayLoan(uint256 loanId) external nonReentrant {
Loan storage loan = loans[loanId];
require(loan.status == LoanStatus.Active, "Loan not active");
require(msg.sender == loan.borrower, "Not borrower");
// Transfer USDC from borrower
USDC.transferFrom(msg.sender, address(this), loan.totalOwed);
// Return collateral
assetTokenizer.transferFrom(address(this), msg.sender, loan.collateralTokenId);
loan.status = LoanStatus.Repaid;
emit LoanRepaid(loanId, loan.totalOwed);
}
function toString(uint256 value) internal pure returns (string memory) {
if (value == 0) return "0";
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
/**
* @title PortfolioToken
* @dev Meta-token wrapping multiple ERC-20s (including other portfolios)
*/
contract PortfolioToken is ERC20 {
struct TokenWeight {
address token;
uint256 weight; // Basis points (10000 = 100%)
}
TokenWeight[] public composition;
mapping(address => uint256) public tokenIndex;
event PortfolioCreated(address indexed creator, uint256 totalSupply);
constructor(
string memory name,
string memory symbol,
TokenWeight[] memory _composition,
uint256 totalSupply
) ERC20(name, symbol) {
require(_composition.length > 0, "Empty portfolio");
uint256 totalWeight = 0;
for (uint256 i = 0; i < _composition.length; i++) {
composition.push(_composition[i]);
tokenIndex[_composition[i].token] = i;
totalWeight += _composition[i].weight;
}
require(totalWeight == 10000, "Weights must sum to 100%");
_mint(msg.sender, totalSupply);
emit PortfolioCreated(msg.sender, totalSupply);
}
function getComposition() external view returns (TokenWeight[] memory) {
return composition;
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
/**
* @title YellowBridge
* @dev Settlement contract for Yellow Network off-chain trading
*/
contract YellowBridge is ReentrancyGuard {
struct Session {
address user;
uint256 depositedAmount;
address token;
uint256 startTime;
bool isActive;
}
mapping(bytes32 => Session) public sessions;
event SessionStarted(bytes32 indexed sessionId, address indexed user, address token, uint256 amount);
event SessionSettled(bytes32 indexed sessionId, uint256 finalBalance);
function startSession(address token, uint256 amount) external nonReentrant returns (bytes32) {
require(amount > 0, "Invalid amount");
bytes32 sessionId = keccak256(abi.encodePacked(msg.sender, token, block.timestamp));
// Lock tokens
IERC20(token).transferFrom(msg.sender, address(this), amount);
sessions[sessionId] = Session({
user: msg.sender,
depositedAmount: amount,
token: token,
startTime: block.timestamp,
isActive: true
});
emit SessionStarted(sessionId, msg.sender, token, amount);
return sessionId;
}
function settleSession(bytes32 sessionId, uint256 finalBalance) external nonReentrant {
Session storage session = sessions[sessionId];
require(session.isActive, "Session not active");
require(msg.sender == session.user, "Not session owner");
require(finalBalance <= session.depositedAmount, "Invalid final balance");
session.isActive = false;
// Return final balance to user
IERC20(session.token).transfer(session.user, finalBalance);
emit SessionSettled(sessionId, finalBalance);
}
}
test/1-AssetTokenizer.test.js:
const { expect } = require("chai");
const { ethers } = require("hardhat");
describe("AssetTokenizer", function () {
let assetTokenizer;
let owner, appraiser, user;
beforeEach(async function () {
[owner, appraiser, user] = await ethers.getSigners();
const AssetTokenizer = await ethers.getContractFactory("AssetTokenizer");
assetTokenizer = await AssetTokenizer.deploy();
});
it("Should tokenize a real-world asset", async function () {
const tx = await assetTokenizer.connect(user).tokenizeAsset(
"real_estate",
500000, // $500k valuation
"QmHash123...",
appraiser.address
);
const receipt = await tx.wait();
const event = receipt.events.find(e => e.event === "AssetTokenized");
const tokenId = event.args.tokenId;
expect(await assetTokenizer.ownerOf(tokenId)).to.equal(user.address);
const asset = await assetTokenizer.getAsset(tokenId);
expect(asset.assetType).to.equal("real_estate");
expect(asset.valuationUSD).to.equal(500000);
expect(asset.isActive).to.be.true;
});
it("Should transfer asset ownership", async function () {
const tx = await assetTokenizer.connect(user).tokenizeAsset(
"invoice",
10000,
"QmInvoice...",
appraiser.address
);
const receipt = await tx.wait();
const tokenId = receipt.events[0].args.tokenId;
await assetTokenizer.connect(user).transferFrom(user.address, owner.address, tokenId);
expect(await assetTokenizer.ownerOf(tokenId)).to.equal(owner.address);
});
});
test/2-LoanFactory.test.js:
const { expect } = require("chai");
const { ethers } = require("hardhat");
describe("LoanFactory", function () {
let loanFactory, assetTokenizer, usdc;
let owner, borrower, lender;
let collateralTokenId;
beforeEach(async function () {
[owner, borrower, lender] = await ethers.getSigners();
// Deploy mock USDC
const MockERC20 = await ethers.getContractFactory("MockERC20");
usdc = await MockERC20.deploy("USD Coin", "USDC", 6);
// Deploy AssetTokenizer
const AssetTokenizer = await ethers.getContractFactory("AssetTokenizer");
assetTokenizer = await AssetTokenizer.deploy();
// Deploy LoanFactory
const LoanFactory = await ethers.getContractFactory("LoanFactory");
loanFactory = await LoanFactory.deploy(usdc.address, assetTokenizer.address);
// Mint USDC to loan factory
await usdc.mint(loanFactory.address, ethers.parseUnits("1000000", 6));
// Borrower tokenizes asset
const tx = await assetTokenizer.connect(borrower).tokenizeAsset(
"real_estate",
300000,
"QmProperty...",
owner.address
);
const receipt = await tx.wait();
collateralTokenId = receipt.events[0].args.tokenId;
});
it("Should create a collateralized loan", async function () {
// Approve collateral
await assetTokenizer.connect(borrower).approve(loanFactory.address, collateralTokenId);
const principal = ethers.parseUnits("100000", 6); // $100k
const interestRate = 500; // 5%
const duration = 365 * 24 * 60 * 60; // 1 year
const tx = await loanFactory.connect(borrower).createLoan(
collateralTokenId,
principal,
interestRate,
duration
);
const receipt = await tx.wait();
const event = receipt.events.find(e => e.event === "LoanCreated");
const loanId = event.args.loanId;
const loan = await loanFactory.loans(loanId);
expect(loan.borrower).to.equal(borrower.address);
expect(loan.principalUSDC).to.equal(principal);
expect(loan.status).to.equal(0); // Active
// Check USDC transferred to borrower
expect(await usdc.balanceOf(borrower.address)).to.equal(principal);
// Check collateral held by contract
expect(await assetTokenizer.ownerOf(collateralTokenId)).to.equal(loanFactory.address);
});
it("Should allow loan repayment", async function () {
await assetTokenizer.connect(borrower).approve(loanFactory.address, collateralTokenId);
const principal = ethers.parseUnits("50000", 6);
const interestRate = 300; // 3%
const duration = 180 * 24 * 60 * 60;
const tx = await loanFactory.connect(borrower).createLoan(
collateralTokenId,
principal,
interestRate,
duration
);
const receipt = await tx.wait();
const loanId = receipt.events.find(e => e.event === "LoanCreated").args.loanId;
const loan = await loanFactory.loans(loanId);
const totalOwed = loan.totalOwed;
// Approve and repay
await usdc.connect(borrower).approve(loanFactory.address, totalOwed);
await loanFactory.connect(borrower).repayLoan(loanId);
const updatedLoan = await loanFactory.loans(loanId);
expect(updatedLoan.status).to.equal(1); // Repaid
// Check collateral returned
expect(await assetTokenizer.ownerOf(collateralTokenId)).to.equal(borrower.address);
});
});
test/3-YellowBridge.test.js:
const { expect } = require("chai");
const { ethers } = require("hardhat");
describe("YellowBridge", function () {
let yellowBridge, token;
let user;
beforeEach(async function () {
[user] = await ethers.getSigners();
const MockERC20 = await ethers.getContractFactory("MockERC20");
token = await MockERC20.deploy("Loan Token", "LOAN", 18);
const YellowBridge = await ethers.getContractFactory("YellowBridge");
yellowBridge = await YellowBridge.deploy();
await token.mint(user.address, ethers.parseEther("1000"));
});
it("Should start a Yellow Network session", async function () {
const depositAmount = ethers.parseEther("100");
await token.connect(user).approve(yellowBridge.address, depositAmount);
const tx = await yellowBridge.connect(user).startSession(token.address, depositAmount);
const receipt = await tx.wait();
const event = receipt.events.find(e => e.event === "SessionStarted");
const sessionId = event.args.sessionId;
const session = await yellowBridge.sessions(sessionId);
expect(session.user).to.equal(user.address);
expect(session.depositedAmount).to.equal(depositAmount);
expect(session.isActive).to.be.true;
// Check tokens locked
expect(await token.balanceOf(yellowBridge.address)).to.equal(depositAmount);
});
it("Should settle session with final balance", async function () {
const depositAmount = ethers.parseEther("100");
await token.connect(user).approve(yellowBridge.address, depositAmount);
const tx = await yellowBridge.connect(user).startSession(token.address, depositAmount);
const receipt = await tx.wait();
const sessionId = receipt.events.find(e => e.event === "SessionStarted").args.sessionId;
const finalBalance = ethers.parseEther("95"); // Lost 5 tokens trading
await yellowBridge.connect(user).settleSession(sessionId, finalBalance);
const session = await yellowBridge.sessions(sessionId);
expect(session.isActive).to.be.false;
expect(await token.balanceOf(user.address)).to.equal(ethers.parseEther("995")); // 1000 - 100 + 95
});
});
scripts/deploy.js:
const hre = require("hardhat");
async function main() {
console.log("Deploying to", hre.network.name);
const [deployer] = await ethers.getSigners();
console.log("Deployer:", deployer.address);
// Deploy AssetTokenizer
console.log("\n1. Deploying AssetTokenizer...");
const AssetTokenizer = await ethers.getContractFactory("AssetTokenizer");
const assetTokenizer = await AssetTokenizer.deploy();
await assetTokenizer.deployed();
console.log("AssetTokenizer deployed to:", assetTokenizer.address);
// Deploy mock USDC (or use real USDC on Arc testnet)
console.log("\n2. Deploying Mock USDC...");
const MockERC20 = await ethers.getContractFactory("MockERC20");
const usdc = await MockERC20.deploy("USD Coin", "USDC", 6);
await usdc.deployed();
console.log("USDC deployed to:", usdc.address);
// Deploy LoanFactory
console.log("\n3. Deploying LoanFactory...");
const LoanFactory = await ethers.getContractFactory("LoanFactory");
const loanFactory = await LoanFactory.deploy(usdc.address, assetTokenizer.address);
await loanFactory.deployed();
console.log("LoanFactory deployed to:", loanFactory.address);
// Deploy YellowBridge
console.log("\n4. Deploying YellowBridge...");
const YellowBridge = await ethers.getContractFactory("YellowBridge");
const yellowBridge = await YellowBridge.deploy();
await yellowBridge.deployed();
console.log("YellowBridge deployed to:", yellowBridge.address);
// Deploy PortfolioFactory
console.log("\n5. Deploying PortfolioFactory...");
const PortfolioFactory = await ethers.getContractFactory("PortfolioFactory");
const portfolioFactory = await PortfolioFactory.deploy();
await portfolioFactory.deployed();
console.log("PortfolioFactory deployed to:", portfolioFactory.address);
console.log("\nโ
Deployment complete!");
console.log("\nSave these addresses:");
console.log({
assetTokenizer: assetTokenizer.address,
usdc: usdc.address,
loanFactory: loanFactory.address,
yellowBridge: yellowBridge.address,
portfolioFactory: portfolioFactory.address
});
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
Deploy command:
# Run all tests first
npx hardhat test
# Deploy to Arc testnet
npx hardhat run scripts/deploy.js --network arcTestnet
# Verify contracts
npx hardhat verify --network arcTestnet DEPLOYED_ADDRESS
src/yellow/YellowClient.js:
import { YellowSDK } from '@yellow-network/sdk';
class YellowClient {
constructor(config) {
this.sdk = new YellowSDK({
network: config.network || 'testnet',
privateKey: config.privateKey
});
}
async createSession(token, amount) {
// Create wallet session
const session = await this.sdk.createSession({
token,
amount,
allowances: {
trading: true,
maxPerTrade: amount * 0.1 // 10% per trade
}
});
return session;
}
async placeOrder(sessionId, order) {
// Off-chain order execution
const result = await this.sdk.trade({
sessionId,
type: order.type, // 'market' or 'limit'
pair: order.pair,
side: order.side, // 'buy' or 'sell'
amount: order.amount,
price: order.price
});
return result;
}
async settleSession(sessionId) {
// Finalize on-chain
const settlement = await this.sdk.settleSession(sessionId);
return settlement;
}
}
export default YellowClient;
src/exchange/OrderBookManager.js:
class OrderBookManager {
constructor(yellowClient, yellowBridgeContract) {
this.yellow = yellowClient;
this.bridge = yellowBridgeContract;
this.activeOrders = new Map();
}
async createLimitOrder(token, amount, price, side) {
// Start Yellow session
const sessionId = await this.bridge.startSession(token, amount);
// Place off-chain limit order
const order = await this.yellow.placeOrder(sessionId, {
type: 'limit',
pair: `${token}/USDC`,
side,
amount,
price
});
this.activeOrders.set(order.id, { sessionId, order });
return order;
}
async executeMarketOrder(token, amount, side) {
const sessionId = await this.bridge.startSession(token, amount);
const result = await this.yellow.placeOrder(sessionId, {
type: 'market',
pair: `${token}/USDC`,
side,
amount
});
// Immediate settlement for market orders
await this.yellow.settleSession(sessionId);
return result;
}
async cancelOrder(orderId) {
const { sessionId } = this.activeOrders.get(orderId);
await this.yellow.cancelOrder(orderId);
await this.yellow.settleSession(sessionId);
this.activeOrders.delete(orderId);
}
}
export default OrderBookManager;
src/lifi/CrossChainManager.js:
import { LiFi } from '@lifi/sdk';
class CrossChainManager {
constructor() {
this.lifi = new LiFi({
integrator: 'defi-tokenizer-platform'
});
}
async depositCollateralFromAnyChain(fromChain, toChain, token, amount, userAddress) {
// Get best route from LI.FI
const quote = await this.lifi.getQuote({
fromChain,
toChain,
fromToken: token,
toToken: 'USDC', // Convert to USDC on Arc
fromAmount: amount,
fromAddress: userAddress,
toAddress: userAddress
});
// Execute cross-chain swap
const result = await this.lifi.executeRoute({
route: quote.routes[0]
});
return result;
}
async rebalancePortfolio(portfolio, targetChain) {
// Multi-chain portfolio rebalancing
const routes = [];
for (const position of portfolio.positions) {
if (position.chain !== targetChain) {
const route = await this.lifi.getQuote({
fromChain: position.chain,
toChain: targetChain,
fromToken: position.token,
toToken: position.token,
fromAmount: position.amount,
fromAddress: portfolio.owner,
toAddress: portfolio.owner
});
routes.push(route.routes[0]);
}
}
// Execute all routes
const results = await Promise.all(
routes.map(route => this.lifi.executeRoute({ route }))
);
return results;
}
}
export default CrossChainManager;
src/agents/StrategyParser.js:
import axios from 'axios';
class StrategyParser {
constructor(ollamaUrl = 'http://localhost:11434') {
this.ollamaUrl = ollamaUrl;
}
async parseUserIntent(userDescription) {
const prompt = `
You are a DeFi strategy parser. Convert this user description into a JSON strategy:
User description: "${userDescription}"
Generate a JSON object with:
{
"type": "rebalancing|arbitrage|hedging|lending",
"triggers": [{"condition": "...", "threshold": ...}],
"actions": [{"type": "...", "params": {...}}],
"constraints": {"maxSlippage": 0.01, "gasLimit": ...}
}
Only respond with valid JSON.
`;
const response = await axios.post(`${this.ollamaUrl}/api/generate`, {
model: 'llama2',
prompt,
stream: false
});
const strategy = JSON.parse(response.data.response);
return strategy;
}
async optimizeStrategy(strategy, marketData) {
const prompt = `
Given this strategy:
${JSON.stringify(strategy, null, 2)}
And market data:
${JSON.stringify(marketData, null, 2)}
Suggest optimizations. Respond with JSON only:
{
"suggestedChanges": [...],
"riskScore": 0-100,
"expectedAPY": ...
}
`;
const response = await axios.post(`${this.ollamaUrl}/api/generate`, {
model: 'llama2',
prompt,
stream: false
});
return JSON.parse(response.data.response);
}
}
export default StrategyParser;
contracts/agents/AgentExecutor.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
contract AgentExecutor is Ownable {
struct Strategy {
bytes32 id;
address owner;
string strategyType;
bool isActive;
uint256 lastExecuted;
}
mapping(bytes32 => Strategy) public strategies;
mapping(address => bytes32[]) public userStrategies;
event StrategyRegistered(bytes32 indexed strategyId, address indexed owner);
event StrategyExecuted(bytes32 indexed strategyId, uint256 timestamp);
constructor() Ownable(msg.sender) {}
function registerStrategy(
string memory strategyType,
bytes memory strategyData
) external returns (bytes32) {
bytes32 strategyId = keccak256(abi.encodePacked(
msg.sender,
strategyType,
block.timestamp
));
strategies[strategyId] = Strategy({
id: strategyId,
owner: msg.sender,
strategyType: strategyType,
isActive: true,
lastExecuted: 0
});
userStrategies[msg.sender].push(strategyId);
emit StrategyRegistered(strategyId, msg.sender);
return strategyId;
}
function executeStrategy(bytes32 strategyId, bytes calldata actionData) external {
Strategy storage strategy = strategies[strategyId];
require(strategy.isActive, "Strategy not active");
// Execute strategy logic (simplified)
// In production: decode actionData and execute trades/rebalancing
strategy.lastExecuted = block.timestamp;
emit StrategyExecuted(strategyId, block.timestamp);
}
}
npm create vite@latest frontend -- --template react
cd frontend
npm install ethers wagmi viem @rainbow-me/rainbowkit
npm install @lifi/widget @lifi/sdk
npm install recharts tailwindcss
npm install @tanstack/react-query
src/components/LoanCreator.jsx:
import { useState } from 'react';
import { useContractWrite } from 'wagmi';
import LOAN_FACTORY_ABI from '../abis/LoanFactory.json';
function LoanCreator({ assetTokenId }) {
const [principal, setPrincipal] = useState('');
const [interestRate, setInterestRate] = useState('5');
const [duration, setDuration] = useState('365');
const { write: createLoan } = useContractWrite({
address: process.env.VITE_LOAN_FACTORY_ADDRESS,
abi: LOAN_FACTORY_ABI,
functionName: 'createLoan'
});
const handleSubmit = () => {
createLoan({
args: [
assetTokenId,
ethers.parseUnits(principal, 6), // USDC has 6 decimals
parseInt(interestRate) * 100, // Convert to basis points
parseInt(duration) * 24 * 60 * 60 // Convert days to seconds
]
});
};
return (
<div className="card">
<h2>Create Collateralized Loan</h2>
<input
type="number"
placeholder="Principal (USDC)"
value={principal}
onChange={(e) => setPrincipal(e.target.value)}
/>
<input
type="number"
placeholder="Interest Rate (%)"
value={interestRate}
onChange={(e) => setInterestRate(e.target.value)}
/>
<input
type="number"
placeholder="Duration (days)"
value={duration}
onChange={(e) => setDuration(e.target.value)}
/>
<button onClick={handleSubmit}>Create Loan</button>
</div>
);
}
export default LoanCreator;
src/components/YellowTrader.jsx:
import { useState } from 'react';
import { useYellowNetwork } from '../hooks/useYellowNetwork';
function YellowTrader({ loanToken }) {
const [amount, setAmount] = useState('');
const [price, setPrice] = useState('');
const { placeOrder, activeSession } = useYellowNetwork();
const handleLimitOrder = async (side) => {
const order = await placeOrder({
type: 'limit',
token: loanToken,
amount: ethers.parseEther(amount),
price: ethers.parseUnits(price, 6),
side
});
console.log('Order placed:', order);
};
return (
<div className="trader-card">
<h3>Trade Loan Token (Gas-Free)</h3>
<p className="yellow-badge">โก Yellow Network - Instant Settlement</p>
<input
type="number"
placeholder="Amount"
value={amount}
onChange={(e) => setAmount(e.target.value)}
/>
<input
type="number"
placeholder="Price (USDC)"
value={price}
onChange={(e) => setPrice(e.target.value)}
/>
<div className="button-group">
<button onClick={() => handleLimitOrder('buy')} className="buy-btn">
Buy
</button>
<button onClick={() => handleLimitOrder('sell')} className="sell-btn">
Sell
</button>
</div>
{activeSession && (
<p className="session-info">
Active Session: {activeSession.id.slice(0, 10)}...
</p>
)}
</div>
);
}
export default YellowTrader;
test/integration/full-flow.test.js:
describe("Full Platform Flow", function () {
it("Should complete RWA โ Loan โ Trade โ Portfolio flow", async function () {
// 1. Tokenize RWA
const assetTx = await assetTokenizer.tokenizeAsset(...);
const assetId = (await assetTx.wait()).events[0].args.tokenId;
// 2. Create loan
await assetTokenizer.approve(loanFactory.address, assetId);
const loanTx = await loanFactory.createLoan(...);
const loanId = (await loanTx.wait()).events[0].args.loanId;
// 3. Start Yellow session
const loan = await loanFactory.loans(loanId);
const sessionTx = await yellowBridge.startSession(loan.loanToken, ethers.parseEther("10"));
const sessionId = (await sessionTx.wait()).events[0].args.sessionId;
// 4. Create portfolio with loan token
const portfolioTx = await portfolioFactory.createPortfolio([
{ token: loan.loanToken, weight: 5000 },
{ token: otherToken.address, weight: 5000 }
], ethers.parseEther("100"));
// 5. Settle Yellow session
await yellowBridge.settleSession(sessionId, ethers.parseEther("9.5"));
// Verify final state
expect(await portfolioToken.balanceOf(owner.address)).to.be.gt(0);
});
});
demo-script.md:
# Demo Video Script (3 minutes)
## Scene 1: Introduction (30s)
"Hi, I'm presenting our DeFi Collateralized Loan Tokenization Platform built for HackMoney 2026.
We've created a meta-tokenization system where users can:
- Tokenize real-world assets
- Create collateralized loans
- Trade positions instantly with zero gas fees
- Build recursive portfolios
- Deploy AI agents for automated strategies
All built on Arc Network, Yellow Network, and LI.FI."
## Scene 2: RWA Tokenization (30s)
[Screen: Asset tokenization form]
"First, I'll tokenize a real estate property worth $500,000.
Upload documentation, get appraiser verification, mint NFT.
This NFT now represents provable ownership on Arc Network."
## Scene 3: Loan Creation (45s)
[Screen: Loan creation interface]
"Using this RWA as collateral, I create a $100k USDC loan at 5% APR.
The loan is automatically tokenized as an ERC-20.
Liquidity providers can now trade fractional loan positions.
All settled in USDC on Arc for maximum compatibility."
## Scene 4: Yellow Network Trading (45s)
[Screen: Trading interface]
"Here's where Yellow Network shines - gas-free trading.
I start a session, deposit my loan tokens, place a limit order.
Trades execute off-chain instantly, no blockchain delays.
When I'm done, final balances settle on-chain in one transaction.
This makes high-frequency DeFi actually usable."
## Scene 5: Cross-Chain & AI Agents (30s)
[Screen: Agent dashboard + LI.FI bridge]
"Using LI.FI, I can deposit collateral from any chain.
My AI agent - powered by Ollama - monitors my portfolio.
I tell it: 'rebalance if correlation exceeds 0.7'
The agent executes cross-chain rebalancing automatically."
## Closing (15s)
"Three sponsor integrations, one platform:
Arc for RWA-backed credit
Yellow for instant trading
LI.FI for cross-chain liquidity
Thanks for watching!"
HACKATHON_SUBMISSION.md:
# DeFi Collateralized Loan Tokenization Platform
## ๐ฏ Project Overview
A meta-tokenization platform enabling users to tokenize real-world assets, create collateralized loans, trade positions with zero gas fees, and deploy AI-powered portfolio management agents. Everything is tokenizable and composable through elegant recursion.
## ๐ Sponsor Prize Targets
### 1. Arc Network - Best Agentic Commerce App Powered by Real-World Assets ($2,500)
**Integration Points:**
- Arc serves as the primary settlement layer for all loan operations
- All loans are denominated in USDC on Arc for maximum stability
- RWA NFTs are minted on Arc with immutable documentation hashes
- AI agents manage USDC-denominated portfolios backed by RWA collateral
- Smart contracts enable autonomous credit decisions based on oracle data
**Why Arc:**
Arc's EVM compatibility and USDC-native infrastructure provide the perfect foundation for RWA-backed lending. Our platform demonstrates how programmable trust enables real economic value transfer through tokenized collateral.
**Demo Transactions:**
- RWA Tokenization: `0x...` (Arc Testnet)
- Loan Creation: `0x...`
- Agent Strategy Execution: `0x...`
### 2. Yellow Network - Trading Apps/Marketplaces (1st place $5,000)
**Integration Points:**
- Yellow SDK integrated for gasless limit and market orders
- Users deposit loan tokens once, trade unlimited times off-chain
- Final settlement occurs only when session ends
- Supports high-frequency trading of loan positions, insurance tokens, and portfolios
- Dramatically improves UX by eliminating per-trade gas costs
**Why Yellow:**
Traditional DeFi trading is prohibitive for loan tokens due to gas costs. Yellow's state channels enable Web2-level trading experience while maintaining Web3 security. This makes our tokenized lending positions actually tradeable.
**Demo Video:**
[3-minute demo showing session creation, 20+ trades, single settlement]
### 3. LI.FI - Best AI x LI.FI Smart App ($2,000)
**Integration Points:**
- Cross-chain collateral deposits from any EVM chain
- AI agents use LI.FI for automated portfolio rebalancing
- Users can leverage liquidity from multiple chains for loans
- Agents monitor correlation and execute cross-chain hedging strategies
**Why LI.FI:**
Real-world assets and collateral exist across multiple chains. LI.FI enables our platform to treat liquidity as one unified market, letting AI agents optimize positions regardless of where assets live.
**Agent Strategy Example:**
```javascript
{
"type": "rebalancing",
"triggers": [{"condition": "correlation > 0.7"}],
"actions": [{"type": "cross_chain_rebalance", "target_chain": "arc"}]
}
โ RWA Tokenization: Mint NFTs for real estate, invoices, equipment with documentation โ Collateralized Loans: USDC loans backed by RWA NFTs, automatically tokenized โ Gasless Trading: Yellow Network state channels for instant, fee-free trading โ Insurance Markets: Create/trade CDS positions for loan default protection โ Recursive Portfolios: Tokenize portfolios of portfolios for complex strategies โ AI Agents: Natural language strategies โ automated execution โ Cross-Chain: Deposit collateral from any chain via LI.FI
[YouTube Link: 3-minute walkthrough]
Demonstrated Flow:
# Run comprehensive test suite
npx hardhat test
# Test coverage
npx hardhat coverage
# Integration tests
npm run test:integration
Test Results:
Arc Testnet:
0x...0x...0x...0x...Frontend: [Vercel deployment link]
GitHub: [repository link]
Structure:
โโโ contracts/ # Solidity smart contracts
โโโ test/ # Comprehensive test suite
โโโ scripts/ # Deployment scripts
โโโ frontend/ # React application
โโโ src/
โ โโโ yellow/ # Yellow SDK integration
โ โโโ lifi/ # LI.FI cross-chain logic
โ โโโ agents/ # AI agent system
โโโ docs/ # Technical documentation
Meta-Tokenization: Everything is composable - loans, insurance, portfolios can all be wrapped into higher-order portfolios recursively
Zero-Gas Trading: Yellow Network makes DeFi positions tradeable like Web2 assets without blockchain friction
RWA-Backed Credit: Arc's USDC infrastructure enables real-world asset collateralization with blockchain security
AI-Powered Strategies: Natural language โ executable code via Ollama, democratizing algorithmic trading
Cross-Chain Unified Liquidity: LI.FI treats all chains as one liquidity surface for maximum capital efficiency
[Your name(s), backgrounds, commitment to continue post-hackathon]
Special thanks to:
Built with โค๏ธ for HackMoney 2026
---
## IDE Agent Instructions
### For Smart Contract Development:
PRIORITY 1: Read all sponsor documentation thoroughly PRIORITY 2: Write tests BEFORE implementing features PRIORITY 3: Deploy to testnet and verify each contract individually
WORKFLOW:
DEBUGGING:
SPONSOR INTEGRATION:
### For Frontend Development:
PRIORITY 1: Get sponsor widgets working before custom UI PRIORITY 2: Use wagmi hooks for all blockchain interactions PRIORITY 3: Handle loading states and errors gracefully
WORKFLOW:
DEBUGGING:
---
## Quick Start Guide
```bash
# Clone and setup
git clone [repo]
cd defi-tokenizer-platform
npm install
# Run tests
npx hardhat test
# Deploy to Arc testnet
npx hardhat run scripts/deploy.js --network arcTestnet
# Start frontend
cd frontend
npm install
npm run dev
# Run Ollama (for AI agents)
ollama pull llama2
ollama serve
โ Arc Prize Requirements:
โ Yellow Prize Requirements:
โ LI.FI Prize Requirements:
This plan provides a complete, step-by-step guide to building a prize-winning hackathon project with proper sponsor integration, comprehensive testing, and a compelling demo. The recursive tokenization architecture keeps development manageable while delivering impressive functionality. Good luck! ๐

