Nolus Docs

NLS rewards

How the Nolus treasury distributes NLS rewards to lending pools by total pool value, how each lender's share accrues, and how to query and claim it.

Besides the interest that positions pay, lenders can earn NLS. The treasury contract distributes NLS to the lending pools on a schedule, each pool shares it among its lenders by their nLPN balance, and lenders claim it whenever they choose. These rewards are separate from the pool's interest, so they do not change the nLPN price and are paid in NLS rather than in the pool currency.

Distribution to pools

The treasury distributes rewards in runs that a time alarm triggers, and each run sizes the rewards by the combined value of all the pools before it shares them out.

On each run, the treasury reads the value of every registered pool and sums them. A tiered table maps that total value of all pools to an annual reward rate, and the treasury applies the highest tier whose minimum the total reaches. Each pool then receives NLS in proportion to its own value, for the time since the last run.

How often the treasury runs is part of its configuration, so reading it starts with the treasury address, which comes from the platform admin contract:

ADMIN=nolus1gurgpv8savnfw66lckwzn4zk7fp394lpe667dhu7aw48u40lj6jsqxf8nd
nolusd q wasm contract-state smart $ADMIN '{"platform":{}}' -o json
# {"data":{"timealarms":"nolus1...","treasury":"nolus1..."}}

The treasury field holds the address. Query the treasury with nolusd q wasm contract-state smart <treasury> '{"config":{}}', replacing <treasury> with that address, and read the cadence from cadence_hours, for example 12.

Accrual per lender

Within a pool, the share of each lender is tracked through a reward index, which is the NLS distributed per nLPN so far. Each lender's record stores their nLPN balance, the index at their last update and the NLS pending since then. Whenever the lender deposits, withdraws or claims, the pool adds nLPN balance x (current index - stored index) to the pending amount and stores the current index. As a result, a lender who deposits after a distribution does not share in it.

Query and claim

A lender's pending rewards in a pool come from the pool's rewards query:

nolusd q wasm contract-state smart $LPP '{"rewards":{"address":"<account>"}}' -o json
# {"data":{"rewards":{"amount":"<unls>"}}}

Replace <account> with the lender's Nolus account, and set $LPP to the pool address as Find and query a pool shows. The amount comes back in unls, where 1 NLS equals 1,000,000 unls, and the query returns an error for an account that has no deposit in the pool.

A claim is the claim_rewards message, which can name a recipient:

{ "claim_rewards": { "other_recipient": "<nolus account>" } }

The other_recipient field is optional and holds the account that receives the NLS. Without it, the NLS goes to the claiming account, which is what the following command does once <key> is replaced with the signing key:

nolusd tx wasm execute $LPP '{"claim_rewards":{}}' \
  --from <key> --gas auto --gas-adjustment 1.3 --gas-prices 0.025unls

A claim with nothing pending is rejected with NoRewards. A full withdrawal pays out pending rewards automatically, so a lender who leaves a pool needs no separate claim. Because every pool keeps its own record, an account that has deposited in several pools claims from each of them.

On this page