drip()method is called. This effectively updates the accumulated debt for all Vaults of that collateral type as well as the total accumulated debt as tracked by the Vat (global) and the amount of dotBTC surplus (represented as the amount of dotBTC owned by the Vow).
Ilk: contains two
duty, the collateral-specific risk premium, and
rho, the timestamp of the last fee update
VatLike: mock contract to make Vat interfaces callable from code without an explicit dependency on the Vat contract itself
mapping(address => uint)that indicates which addresses may call administrative functions
mapping (bytes32 => Ilk)that stores an
Ilkstruct for each collateral type
addressof the Vow contract
uint256that specifies a fee applying to all collateral types
wards[msg.sender] == 1(i.e. only authorized users may call them).
deny: add or remove authorized users (via modifications to the
init(bytes32): start stability fee collection for a particular collateral type
file(bytes32, bytes32, uint): set
dutyfor a particular collateral type
file(bytes32, data): set the
file(bytes32, address): set the
drip(bytes32): collect stability fees for a given collateral type
drip(bytes32 ilk)performs stability fee collection for a specific collateral type when it is called (note that it is a public function and may be called by anyone).
dripdoes essentially three things:
ilkbased on the time elapsed since the last update and the current instantaneous rate (
base + duty);
Vat.foldto update the collateral's
rate, total tracked debt, and Vow surplus;
ilks[ilk].rhoto be equal to the current timestamp.
Vat.ilks[ilk].rate, "base" is
Jug.base, "rho" is
Jug.ilks[ilk].rho, and "duty" is
Jug.ilks[ilk].duty. The function reverts if any sub-calculation results in under- or overflow. Refer to the Vat documentation for more detail on
rpow(uint x, uint n, uint b), used for exponentiation in
drip, is a fixed-point arithmetic function that raises
xto the power
n. It is implemented in Solidity assembly as a repeated squaring algorithm.
xand the returned value are to be interpreted as fixed-point integers with scaling factor
b. For example, if
b == 100, this specifies two decimal digits of precision and the normal decimal value 2.1 would be represented as 210;
rpow(210, 2, 100)returns 441 (the two-decimal digit fixed-point representation of 2.1^2 = 4.41). In the current implementation, 10^27 is passed for
rpowresult both of type
rayin standard MCD fixed-point terminology.
rpow's formal invariants include "no overflow" as well as constraints on gas usage.
init(bytes32 ilk)must called when a new collateral is added (setting
file()is not sufficient)—otherwise
rhowill be uninitialized and fees will accumulate based on a start date of January 1st, 1970 (start of Unix epoch).
base + Ilk.dutyimbalance in
drip(bytes32 ilk)will add the
baserate to the
Ilk.dutyrate. The rate is a calculated compounded rate, so
rate(base + duty) != rate(base) + rate(duty). This means that if base is set, the duty will need to be set factoring the existing compounding factor in base, otherwise the result will be outside of the rate tolerance. Updates to the
basevalue will require all of the
ilksto be updated as well.
drip()is called very infrequently for some collateral types (due, for example, to low overall system usage or extremely stable collateral types that have essentially zero liquidation risk), then the system will fail to collect fees on Vaults opened and closed between
drip()calls. As the system achieves scale, this becomes less of a concern, as both Keepers and ABM holders are have an incentive to regularly call drip (the former to trigger liquidation auctions, the latter to ensure that surplus accumulates to decrease ABM supply); however, a hypothetical asset with very low volatility yet high risk premium might still see infrequent drip calls at scale (there is not at present a real-world example of this—the most realistic possibility is
basebeing large, elevating rates for all collateral types).
duty(for at least one ilk) or
basetoo low can lead to dotBTC oversupply; setting either one too high can trigger excess liquidations and therefore unjust loss of collateral. Setting a value for
vowother than the true Vow's address can cause surplus to be lost or stolen.