DpExchange.Core.Types.StakingRate (DpExchangeCore v0.3.1)

Copy Markdown View Source

What one provider pays for staking one asset.

Rates carry their unit, because venues do not agree on one

Gemini publishes rate in basis points, ratePct as a percentage, and apyPct as an annualised percentage — three numbers for the same position, differing by a factor of a hundred and by compounding. A contract that carried "the rate" would be inviting a caller to be wrong by 100×, and the error would look plausible either way.

So this carries percentages only, both named for what they are:

  • :rate_pct — the simple rate, as a percentage
  • :apy_pct — the annualised yield, as a percentage

A venue publishing basis points converts on the way in. A venue publishing only one of the two leaves the other nil rather than deriving it: turning a simple rate into an APY needs a compounding frequency the venue did not state, and assuming one is inventing a number.

:deposit_limit_usd is a real constraint

Venues cap how much new notional can earn the advertised rate. A caller staking past the cap does not get an error — it gets a worse rate on the excess, silently. Carried where the venue publishes it.

Summary

Functions

Converts a rate in basis points to a percentage.

Builds a t/0, failing closed if a required field is absent or nil.

Types

t()

@type t() :: %DpExchange.Core.Types.StakingRate{
  apy_pct: Decimal.t() | nil,
  asset: String.t(),
  deposit_limit_usd: Decimal.t() | nil,
  provider: atom(),
  provider_id: String.t() | nil,
  rate_pct: Decimal.t() | nil,
  venue_time: DateTime.t() | nil
}

Functions

bps_to_pct(bps)

@spec bps_to_pct(Decimal.t() | number() | String.t()) :: Decimal.t()

Converts a rate in basis points to a percentage.

Provided here rather than left to each venue package, because it is the conversion most likely to be done inconsistently — and a rate wrong by 100× still looks like a rate.

new(attrs)

@spec new(keyword() | map()) :: t()

Builds a t/0, failing closed if a required field is absent or nil.

@enforce_keys guards presence, not nil — see DpExchange.Core.Types.Validate.