Architecture
The contracts behind each Nolus protocol and the platform, how to discover their addresses, the off-chain services, and how positions run on Solana.
Nolus is built in three layers that work together. The protocol contracts on Nolus run the markets, from positions and lending pools to prices and the registry of every protocol, while Solray, the Nolus program on Solana, holds position assets there and runs their swaps. A small set of off-chain services connects the two by feeding prices, triggering alarms and relaying IBC packets between Nolus and Solana.
Integrators mostly work with the contracts on Nolus, discovering their addresses from the admin contract, querying them for state and sending them JSON messages, because everything that happens on Solana is driven by those contracts.
Nolus is deployed on a purpose-built, semi-permissioned ledger, and node operators find its details under Run a full node.
The following diagram shows how these layers connect, from the app that opens a position on Nolus to the swap through Metis on Solana.
Contracts per protocol
Nolus runs one protocol per market, and each protocol is a full set of the
contracts in the following table, registered in the admin contract under a
name such as SOLANA-METIS-USDC. The table gives each contract's role and the
queries that integrators use most.
| Contract | Role | Useful queries |
|---|---|---|
| Leaser | Opens positions, quotes them, and keeps the registry of each user's positions. Holds the protocol's position parameters. | {"config":{}}, {"quote":{...}}, {"leases":{"owner":"<nolus account>"}} |
| Lease | One contract per position. A state machine that tracks the loan, interest and status, and drives the position's account on Solana. | {"state":{}} |
| LPP | The lending pool for the protocol's pool currency (LPN). Lends to positions, and lenders receive nLPN pool shares. | {"lpn":[]}, {"config":[]}, {"lpp_balance":[]}, {"price":[]} |
| Oracle | Aggregates feeder prices into one price per currency and fires price alarms for positions. | {"config":{}}, {"prices":{}}, {"currencies":{}} |
| Profit | Collects margin interest. | |
| Reserve | Covers shortfalls when a position closes or is liquidated for less than it owes. | |
| Remote lease controller | The IBC endpoint on Nolus that drives each position's account in Solray's Remote Lease app. |
In the queries, <nolus account> stands for the user's Nolus account. The
Spot Margin and Lending pages give
the full JSON messages for the Leaser, Lease and LPP, and the
Oracle page covers the oracle queries.
Platform contracts
Alongside the contracts of each protocol, Nolus runs a few platform contracts that all protocols share:
| Contract | Role |
|---|---|
| Admin | The registry of every protocol and platform contract. It also coordinates contract migrations across them. It holds no user funds. |
| Treasury | Distributes NLS rewards to lending pools for lenders, and receives transaction fees paid in NLS. |
| Time alarms | Schedules time-based callbacks, for example a position's periodic re-check. |
Discover contract addresses
Read contract addresses from the admin contract instead of hard-coding them from a list, because the admin contract always reflects the live set. The admin contract has the following address:
nolus1gurgpv8savnfw66lckwzn4zk7fp394lpe667dhu7aw48u40lj6jsqxf8ndThree queries to the admin contract cover discovery, and the following table shows what each one returns:
| Query | Returns |
|---|---|
{"protocols":{}} | The names of all registered protocols. |
{"protocol":"SOLANA-METIS-USDC"} | The protocol's network, dex and contract addresses: leaser, lpp, oracle, profit, reserve, remote_lease. |
{"platform":{}} | The platform contracts: timealarms and treasury. |
With nolusd, the following commands store the admin address and query the
contracts of SOLANA-METIS-USDC:
ADMIN=nolus1gurgpv8savnfw66lckwzn4zk7fp394lpe667dhu7aw48u40lj6jsqxf8nd
nolusd q wasm contract-state smart $ADMIN '{"protocol":"SOLANA-METIS-USDC"}'ADMIN holds the admin contract address, and the next example reuses it. Over
the public LCD, the query message is base64-encoded into the URL, which the
following commands do for the same query:
MSG=$(printf '%s' '{"protocol":"SOLANA-METIS-USDC"}' | base64 -w0)
curl -s "https://lcd.nolus.network/cosmwasm/wasm/v1/contract/$ADMIN/smart/$MSG"Here MSG holds the base64-encoded query, and ADMIN is the variable from
the previous example. For example, the response for SOLANA-METIS-USDC looks
like this:
{
"data": {
"network": "Solana",
"dex": "Metis",
"contracts": {
"leaser": "nolus123v3560y4r5es0w85crkrflx36vprfesw7yst2xqzgpxjpfnfdzqx6dh4h",
"lpp": "nolus1f0pqlmj609l8cy74g65737usspn38sfqyf7pprdef5knv8mm50ss06qlfw",
"oracle": "nolus10uqt28l2kwxp3e5rvpjay09lwardxetz6jxategehxz3l2me8uaqgkmaun",
"profit": "nolus1ut29qgydvpmllwclqdpzf9rzny0q5vqfapf6ylpd83z6arj9gsuqd5ctkn",
"remote_lease": "nolus1xd9sgdu3lvwm0pzrxg3c3lxwvuwkc6jgzk43zkgzjnndrdp5shvsfv3uzp",
"reserve": "nolus12vvr69ua0ynzgyefrwl8gmx5afjsurgj2s72wnxcx8f4rehhedwqpxkdfy"
}
}
}The registry leaves out Lease contracts, so a user's positions come from the
Leaser's {"leases":{"owner":"<nolus account>"}} query instead, which returns
the addresses of the user's Lease contracts.
Off-chain services
Three off-chain services keep the contracts supplied with prices, alarms and packets. Several independent price feeders take prices from Metis quotes on Solana and push them to each protocol's oracle, and the alarms dispatcher triggers due time alarms and price alarms, so that positions re-check themselves when a price moves or a timer expires. Between Nolus and Solana, relayers carry the IBC packets, as IBC in brief describes.
How Nolus drives a position on Solana
Each position has two halves, the Lease contract on Nolus, which keeps the loan and the state, and an account in Solray's Remote Lease app on Solana, which holds the asset. The Lease controls its Solana account over IBC through the protocol's remote lease controller.
Tokens stay on Solana throughout, because the Lease redeems receipts into its Solana account and receives receipts back through Solray's token transfer, while swaps run on Solana through Metis. No Interchain Account (ICA) and no Cosmos host chain take part in this.
Opening, repaying, closing and liquidating all use these pieces in the same way. Whenever the position needs tokens on Solana, the Lease redeems receipts into its account, and swaps run there through Metis. Tokens that leave the account return to Solray's escrow, where Nolus credits receipts for them to the Lease or, after a full repayment, to the user. Positions on Solana names the Solray instructions behind each step, while Opening a position and Repaying and closing give the messages and states on Nolus. The Solray page also has the program reference and describes token transfer and timeouts.
Protocol overview
How Nolus works end to end, covering users and lenders, markets, where position assets live on Solana, the life of a position and fixed-rate interest.
Solray
Solray, the Nolus program on Solana. How tokens stay on Solana while Nolus holds receipts, how positions run there, and the program ID, IDL and instructions.