Ilk
struct that contains the cumulative rate (rate
) and the total normalized debt associated with that collateral type (Art
). The Jug stores the per-second rate for each collateral type as a combination of a base
value that applies to all collateral types, and a duty
value per collateral. The per-second rate for a given collateral type is the sum of its particular duty
and the global base
.Jug.drip(bytes32 ilk)
computes an update to the ilk's rate
based on duty
, base
, and the time since drip
was last called for the given ilk (rho
). Then the Jug invokes Vat.fold(bytes32 ilk, address vow, int rate_change)
which:rate_change
to rate
for the specified ilkArt*rate_change
.Urn
struct in the Vat) stores a "normalized debt" parameter called art
. Any time it is needed by the code, the Vault's total debt, including stability fees, can be calculated as art*rate
(where rate
corresponds to that of the appropriate collateral type). Thus an update to Ilk.rate
via Jug.drip(bytes32 ilk)
effectively updates the debt for all Vaults collateralized with ilk
tokens.rate
is 1; this implies that the stored art
in the Vault's Urn
is also 20. Let the base
and duty
be set such that after 12 years, art*rate
= 30 (this corresponds to an annual stability of roughly 3.4366%). Equivalently, rate
= 1.5 after 12 years. Assuming that base + duty
does not change, the growth of the effective debt can be graphed as follows:art
would be stored in the Vat to reflect this change? (hint: not 30!) Recall that art
is defined from the requirement that art * rate
= Vault debt. Since the Vault's debt is known to be 40 and rate
is known to be 1.5, we can solve for art
: 40/1.5 ~ 26.67.art
can be thought of as "debt at time 0", or "the amount of dotBTC that if drawn at time zero would result in the present total debt". The graph below demonstrates this visually; the length of the green bar extending upwards from t = 0 is the post-draw art
value.rate
rate
value for each collateral perpetually increases (unless the fee becomes negative at some point)drip
?drip
rather than, say, automatically calling it upon Vault manipulations. The following entities are motivated to call drip
:drip
prior to drawing from their Vault, they will be charged fees on the drawn dotBTC going back to the last time drip
was called—unless no one calls drip
before they repay their Vault, see below)drip
are likely to be intermittent due to gas costs and tragedy of the commons until a certain scale can be achieved. Thus the value of the rate
parameter for a given collateral type may display the following time behavior:rate
updates (i.e. between drip
calls) would have no stability fees assessed on it. Also, depending on the timing of updates to the stability fee, there may be small discrepancies between the actual value of rate
and its ideal value (the value if drip
were called in every block). To demonstrate this, consider the following:drip
is called—now:drip
is called again; the actual value of rate
that obtains is:rate
(if drip
were called at the start of every block) would be:drip
calls will be frequent enough such inaccuracies will be minor, at least after an initial growth period. Governance can mitigate this behavior by calling drip
immediately prior to fee changes. The code in fact enforces that drip
must be called prior to a duty
update, but does not enforce a similar restriction for base
(due to the inefficiency of iterating over all collateral types).pie[usr]
) and maintains a cumulative interest rate parameter (chi
). A drip
function analogous to that of Jug is called intermittently by economic actors to trigger savings accumulation.dsr
parameter (analogous to base+duty
in the stability fee case). The chi
parameter as a function of time is thus (in the ideal case of drip
being called every block) given by:chi
effectively increase all Pot balances at once, without having to iterate over all of them.chi
, Pot.drip
then calls Vat.suck
with arguments such that the additional dotBTC created from this savings accumulation is credited to the Pot contract while the Vow's sin
(unbacked debt) is increased by the same amount (the global debt and unbacked debt tallies are increased as well). To accomplish this efficiently, the Pot keeps track of a the total sum of all individual pie[usr]
values in a variable called Pie
.drip
is called only infrequently, the instantaneously value of chi
may differ from the idealdrip
be called prior to dsr
changes, which eliminates deviations of chi
from its ideal value due to such changes not coinciding with drip
callschi
is a monotonically increasing value unless the effective savings rate becomes negative (dsr
< ONE
)dsr
drip
?Pot.drip
:drip
to be called in the same block as new dotBTC is added to the Pot (otherwise, an economic exploit that drains system surplus is possible)dsr
parameter in the Pot implementation is interpreted as a ray
, i.e. a 27 decimal digit fixed-point number. Thus we multiply by 10^27 and drop anything after the decimal point:dsr
could then be set to 0.5% annually by calling:Pot.file("dsr", 1000000000158153903837946258)