Eight modules.
Each module owns one job and reads the others through their public interfaces. Nothing is upgradeable and no module can rewrite another's accounting.
The eight modules
| Module | Controls |
|---|---|
| Broker | the ERC-721, supply, mint price, license tiers and weights |
| ERC6551Registry | deriving and deploying account addresses |
| BrokerAccount | the account implementation each Broker controls |
| Distributor | fee accrual by weight, and claims |
| StockDesk | hStock listings, quotes, buys and redemptions |
| hStock | a single tokenised underlying |
| BrokerMarket | the fixed-price shelf for whole Brokers |
| CreditDesk | the lending pool, loans and liquidation |
Broker
The token itself, and the source of truth for licensing. Weight lives here, keyed by token id, which is why it survives every transfer.
function mint(uint256 qty) payable returns (uint256)
function license(uint256 id, uint8 tier) payable
function tierOf(uint256 id) view returns (uint8)
function tierWeight(uint8 tier) view returns (uint256)
function licensePrice(uint8 tier) view returns (uint256)
function totalWeight() view returns (uint256)
licensePrice is cumulative, so an upgrade charges the difference between the
target tier and the tier already held.
Registry & account
The registry derives an address from the implementation, a salt, the chain id, the token contract and the token id. The same inputs always produce the same address, and deploying twice is harmless.
function account(address impl, bytes32 salt, uint256 chainId,
address tokenContract, uint256 tokenId) view returns (address)
function createAccount(address impl, bytes32 salt, uint256 chainId,
address tokenContract, uint256 tokenId) returns (address)
The account exposes an owner lookup and one executor. Authority is read live, never stored.
function owner() view returns (address)
function execute(address to, uint256 value, bytes data, uint8 op)
payable returns (bytes)
Distributor
Holds one accumulator. Revenue arrives from three places, and each Broker pulls its share based on weight. Claims are pull-only, so nothing is ever pushed to a holder on a schedule.
function pendingOf(uint256 id) view returns (uint256)
function claim(uint256 id) returns (uint256)
function totalFunded() view returns (uint256)
function totalClaimed() view returns (uint256)
| Source | Rate | Paid by |
|---|---|---|
| Broker Market sales | 2.5% | the buyer's payment, before the seller is paid |
| StockDesk fills | 1.0% | each hStock buy and redemption |
| Credit interest | 20% of interest | borrowers, on repayment or liquidation |
StockDesk
Lists hStocks and quotes them. A buy is expected to come from a Broker's account rather than a wallet, which is what puts the position inside the Broker.
function listings(uint256 i) view returns (address)
function priceOf(address hstock) view returns (uint256)
function buy(address hstock) payable returns (uint256)
function redeem(address hstock, uint256 amount) returns (uint256)
BrokerMarket
The shelf. Fixed asks, no bidding, and the seller keeps custody until a sale lands.
function list(uint256 id, uint256 price)
function reprice(uint256 id, uint256 price)
function delist(uint256 id)
function buy(uint256 id) payable
function claimFor(uint256 id) returns (uint256)
function slot(uint256 i) view
returns (uint256 id, address seller, uint256 price, uint8 tier, uint256 pending)
CreditDesk
A share-based lending pool. Lenders deposit ETH for shares; borrowers pledge a Broker, which pledges its account and everything in it. Loans run 30 days at 12% simple interest, with 80% of interest to lenders and 20% to the Distributor.
function totalAssets() view returns (uint256)
function cash() view returns (uint256)
function sharesOf(address who) view returns (uint256)
function previewWithdraw(uint256 shares) view returns (uint256)
function principalOutstanding() view returns (uint256)
function maxBorrow(uint256 id) view returns (uint256)
Withdrawals are limited by idle cash. When most of the pool is out on loan, a lender may have to wait for repayments before exiting in full.
Addresses
Placeholder addresses for this demonstration build. Nothing is deployed and none of these resolve on a live network.
| Module | Address |
|---|---|
| Broker | 0x4C21e0Bf7a9D5e3814bC0a62F7d938Ae15b04C7E |
| ERC6551Registry | 0x6551C0Fd2a4b81E7395fA0cB3d7e6284Bb19f3b2 |
| BrokerAccount | 0x91Fa7c05Be284d16037aC9e5B8f0d24A6c3E1097 |
| Distributor | 0xD37b0e94Ac16F52812bB7a0e6C4f9d85A2107Be3 |
| StockDesk | 0x2A8fE04b91cD673d5810aB7f2e9c40D6a5B31F8C |
| BrokerMarket | 0x7E13a5cB08fD429e6152bA0d7c8f31A9e04B26D5 |
| CreditDesk | 0xB5c904Ae1f7D3628b019aC5eF2d8417a63C0912B |