Meridian
Contracts

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

ModuleControls
Brokerthe ERC-721, supply, mint price, license tiers and weights
ERC6551Registryderiving and deploying account addresses
BrokerAccountthe account implementation each Broker controls
Distributorfee accrual by weight, and claims
StockDeskhStock listings, quotes, buys and redemptions
hStocka single tokenised underlying
BrokerMarketthe fixed-price shelf for whole Brokers
CreditDeskthe 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)
SourceRatePaid by
Broker Market sales2.5%the buyer's payment, before the seller is paid
StockDesk fills1.0%each hStock buy and redemption
Credit interest20% of interestborrowers, 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.

ModuleAddress
Broker0x4C21e0Bf7a9D5e3814bC0a62F7d938Ae15b04C7E
ERC6551Registry0x6551C0Fd2a4b81E7395fA0cB3d7e6284Bb19f3b2
BrokerAccount0x91Fa7c05Be284d16037aC9e5B8f0d24A6c3E1097
Distributor0xD37b0e94Ac16F52812bB7a0e6C4f9d85A2107Be3
StockDesk0x2A8fE04b91cD673d5810aB7f2e9c40D6a5B31F8C
BrokerMarket0x7E13a5cB08fD429e6152bA0d7c8f31A9e04B26D5
CreditDesk0xB5c904Ae1f7D3628b019aC5eF2d8417a63C0912B