Nolus Docs

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.

ContractRoleUseful queries
LeaserOpens positions, quotes them, and keeps the registry of each user's positions. Holds the protocol's position parameters.{"config":{}}, {"quote":{...}}, {"leases":{"owner":"<nolus account>"}}
LeaseOne contract per position. A state machine that tracks the loan, interest and status, and drives the position's account on Solana.{"state":{}}
LPPThe lending pool for the protocol's pool currency (LPN). Lends to positions, and lenders receive nLPN pool shares.{"lpn":[]}, {"config":[]}, {"lpp_balance":[]}, {"price":[]}
OracleAggregates feeder prices into one price per currency and fires price alarms for positions.{"config":{}}, {"prices":{}}, {"currencies":{}}
ProfitCollects margin interest.
ReserveCovers shortfalls when a position closes or is liquidated for less than it owes.
Remote lease controllerThe 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:

ContractRole
AdminThe registry of every protocol and platform contract. It also coordinates contract migrations across them. It holds no user funds.
TreasuryDistributes NLS rewards to lending pools for lenders, and receives transaction fees paid in NLS.
Time alarmsSchedules 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:

nolus1gurgpv8savnfw66lckwzn4zk7fp394lpe667dhu7aw48u40lj6jsqxf8nd

Three queries to the admin contract cover discovery, and the following table shows what each one returns:

QueryReturns
{"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.

On this page