pragma solidity 0.6.7;
contract GebMath {
uint256 public constant RAY = 10 ** 27;
uint256 public constant WAD = 10 ** 18;
function ray(uint x) public pure returns (uint z) {
z = multiply(x, 10 ** 9);
}
function rad(uint x) public pure returns (uint z) {
z = multiply(x, 10 ** 27);
}
function minimum(uint x, uint y) public pure returns (uint z) {
z = (x <= y) ? x : y;
}
function addition(uint x, uint y) public pure returns (uint z) {
z = x + y;
require(z >= x, "uint-uint-add-overflow");
}
function subtract(uint x, uint y) public pure returns (uint z) {
z = x - y;
require(z <= x, "uint-uint-sub-underflow");
}
function multiply(uint x, uint y) public pure returns (uint z) {
require(y == 0 || (z = x * y) / y == x, "uint-uint-mul-overflow");
}
function rmultiply(uint x, uint y) public pure returns (uint z) {
z = multiply(x, y) / RAY;
}
function rdivide(uint x, uint y) public pure returns (uint z) {
z = multiply(x, RAY) / y;
}
function wdivide(uint x, uint y) public pure returns (uint z) {
z = multiply(x, WAD) / y;
}
function wmultiply(uint x, uint y) public pure returns (uint z) {
z = multiply(x, y) / WAD;
}
function rpower(uint x, uint n, uint base) public pure returns (uint z) {
assembly {
switch x case 0 {switch n case 0 {z := base} default {z := 0}}
default {
switch mod(n, 2) case 0 { z := base } default { z := x }
let half := div(base, 2) // for rounding.
for { n := div(n, 2) } n { n := div(n,2) } {
let xx := mul(x, x)
if iszero(eq(div(xx, x), x)) { revert(0,0) }
let xxRound := add(xx, half)
if lt(xxRound, xx) { revert(0,0) }
x := div(xxRound, base)
if mod(n,2) {
let zx := mul(z, x)
if and(iszero(iszero(x)), iszero(eq(div(zx, x), z))) { revert(0,0) }
let zxRound := add(zx, half)
if lt(zxRound, zx) { revert(0,0) }
z := div(zxRound, base)
}
}
}
}
}
}
abstract contract StabilityFeeTreasuryLike {
function getAllowance(address) virtual external view returns (uint, uint);
function systemCoin() virtual external view returns (address);
function pullFunds(address, address, uint) virtual external;
}
contract IncreasingTreasuryReimbursement is GebMath {
// --- Auth ---
mapping (address => uint) public authorizedAccounts;
/**
* @notice Add auth to an account
* @param account Account to add auth to
*/
function addAuthorization(address account) virtual external isAuthorized {
authorizedAccounts[account] = 1;
emit AddAuthorization(account);
}
/**
* @notice Remove auth from an account
* @param account Account to remove auth from
*/
function removeAuthorization(address account) virtual external isAuthorized {
authorizedAccounts[account] = 0;
emit RemoveAuthorization(account);
}
/**
* @notice Checks whether msg.sender can call an authed function
**/
modifier isAuthorized {
require(authorizedAccounts[msg.sender] == 1, "IncreasingTreasuryReimbursement/account-not-authorized");
_;
}
// --- Variables ---
// Starting reward for the fee receiver/keeper
uint256 public baseUpdateCallerReward; // [wad]
// Max possible reward for the fee receiver/keeper
uint256 public maxUpdateCallerReward; // [wad]
// Max delay taken into consideration when calculating the adjusted reward
uint256 public maxRewardIncreaseDelay; // [seconds]
// Rate applied to baseUpdateCallerReward every extra second passed beyond a certain point (e.g next time when a specific function needs to be called)
uint256 public perSecondCallerRewardIncrease; // [ray]
// SF treasury
StabilityFeeTreasuryLike public treasury;
// --- Events ---
event AddAuthorization(address account);
event RemoveAuthorization(address account);
event ModifyParameters(
bytes32 parameter,
address addr
);
event ModifyParameters(
bytes32 parameter,
uint256 val
);
event FailRewardCaller(bytes revertReason, address feeReceiver, uint256 amount);
constructor(
address treasury_,
uint256 baseUpdateCallerReward_,
uint256 maxUpdateCallerReward_,
uint256 perSecondCallerRewardIncrease_
) public {
if (address(treasury_) != address(0)) {
require(StabilityFeeTreasuryLike(treasury_).systemCoin() != address(0), "IncreasingTreasuryReimbursement/treasury-coin-not-set");
}
require(maxUpdateCallerReward_ >= baseUpdateCallerReward_, "IncreasingTreasuryReimbursement/invalid-max-caller-reward");
require(perSecondCallerRewardIncrease_ >= RAY, "IncreasingTreasuryReimbursement/invalid-per-second-reward-increase");
authorizedAccounts[msg.sender] = 1;
treasury = StabilityFeeTreasuryLike(treasury_);
baseUpdateCallerReward = baseUpdateCallerReward_;
maxUpdateCallerReward = maxUpdateCallerReward_;
perSecondCallerRewardIncrease = perSecondCallerRewardIncrease_;
maxRewardIncreaseDelay = uint(-1);
emit AddAuthorization(msg.sender);
emit ModifyParameters("treasury", treasury_);
emit ModifyParameters("baseUpdateCallerReward", baseUpdateCallerReward);
emit ModifyParameters("maxUpdateCallerReward", maxUpdateCallerReward);
emit ModifyParameters("perSecondCallerRewardIncrease", perSecondCallerRewardIncrease);
}
// --- Boolean Logic ---
function either(bool x, bool y) internal pure returns (bool z) {
assembly{ z := or(x, y)}
}
// --- Treasury ---
/**
* @notice This returns the stability fee treasury allowance for this contract by taking the minimum between the per block and the total allowances
**/
function treasuryAllowance() public view returns (uint256) {
(uint total, uint perBlock) = treasury.getAllowance(address(this));
return minimum(total, perBlock);
}
/*
* @notice Get the SF reward that can be sent to a function caller right now
* @param timeOfLastUpdate The last time when the function that the treasury pays for has been updated
* @param defaultDelayBetweenCalls Enforced delay between calls to the function for which the treasury reimburses callers
*/
function getCallerReward(uint256 timeOfLastUpdate, uint256 defaultDelayBetweenCalls) public view returns (uint256) {
// If the rewards are null or if the time of the last update is in the future or present, return 0
bool nullRewards = (baseUpdateCallerReward == 0 && maxUpdateCallerReward == 0);
if (either(timeOfLastUpdate >= now, nullRewards)) return 0;
// If the time elapsed is smaller than defaultDelayBetweenCalls or if the base reward is zero, return 0
uint256 timeElapsed = (timeOfLastUpdate == 0) ? defaultDelayBetweenCalls : subtract(now, timeOfLastUpdate);
if (either(timeElapsed < defaultDelayBetweenCalls, baseUpdateCallerReward == 0)) {
return 0;
}
// If too much time elapsed, return the max reward
uint256 adjustedTime = subtract(timeElapsed, defaultDelayBetweenCalls);
uint256 maxPossibleReward = minimum(maxUpdateCallerReward, treasuryAllowance() / RAY);
if (adjustedTime > maxRewardIncreaseDelay) {
return maxPossibleReward;
}
// Calculate the reward
uint256 calculatedReward = baseUpdateCallerReward;
if (adjustedTime > 0) {
calculatedReward = rmultiply(rpower(perSecondCallerRewardIncrease, adjustedTime, RAY), calculatedReward);
}
// If the reward is higher than max, set it to max
if (calculatedReward > maxPossibleReward) {
calculatedReward = maxPossibleReward;
}
return calculatedReward;
}
/**
* @notice Send a stability fee reward to an address
* @param proposedFeeReceiver The SF receiver
* @param reward The system coin amount to send
**/
function rewardCaller(address proposedFeeReceiver, uint256 reward) internal {
// If the receiver is the treasury itself or if the treasury is null or if the reward is zero, return
if (address(treasury) == proposedFeeReceiver) return;
if (either(address(treasury) == address(0), reward == 0)) return;
// Determine the actual receiver and send funds
address finalFeeReceiver = (proposedFeeReceiver == address(0)) ? msg.sender : proposedFeeReceiver;
try treasury.pullFunds(finalFeeReceiver, treasury.systemCoin(), reward) {}
catch(bytes memory revertReason) {
emit FailRewardCaller(revertReason, finalFeeReceiver, reward);
}
}
}
abstract contract OracleLike {
function getResultWithValidity() virtual external view returns (uint256, bool);
}
abstract contract AccountingEngineLike {
function modifyParameters(bytes32, uint256) virtual external;
}
contract DebtAuctionInitialParameterSetter is IncreasingTreasuryReimbursement {
// --- Variables ---
// Delay between updates after which the reward starts to increase
uint256 public updateDelay;
// Last timestamp when the median was updated
uint256 public lastUpdateTime; // [unix timestamp]
// Min amount of protocol tokens that should be offered in the auction
uint256 public minProtocolTokenAmountOffered; // [wad]
// Premium subtracted from the new amount of protocol tokens to be offered
uint256 public protocolTokenPremium; // [thousand]
// Value of the initial debt bid
uint256 public bidTargetValue; // [wad]
// Delay between two consecutive updates
uint256 public bidValueInflationDelay;
// The target inflation applied to bidTargetValue
uint256 public bidValueTargetInflation;
// The last time when inflation was applied to the bid target value
uint256 public bidValueLastInflationUpdateTime; // [unix timestamp]
// The protocol token oracle
OracleLike public protocolTokenOrcl;
// The system coin oracle
OracleLike public systemCoinOrcl;
// The accounting engine contract
AccountingEngineLike public accountingEngine;
// Max inflation per period
uint256 public constant MAX_INFLATION = 50;
// --- Events ---
event SetDebtAuctionInitialParameters(uint256 debtAuctionBidSize, uint256 initialDebtAuctionMintedTokens);
constructor(
address protocolTokenOrcl_,
address systemCoinOrcl_,
address accountingEngine_,
address treasury_,
uint256 updateDelay_,
uint256 baseUpdateCallerReward_,
uint256 maxUpdateCallerReward_,
uint256 perSecondCallerRewardIncrease_,
uint256 minProtocolTokenAmountOffered_,
uint256 protocolTokenPremium_,
uint256 bidTargetValue_
) public IncreasingTreasuryReimbursement(treasury_, baseUpdateCallerReward_, maxUpdateCallerReward_, perSecondCallerRewardIncrease_) {
require(minProtocolTokenAmountOffered_ > 0, "DebtAuctionInitialParameterSetter/null-min-prot-amt");
require(protocolTokenPremium_ < THOUSAND, "DebtAuctionInitialParameterSetter/invalid-prot-token-premium");
require(both(both(protocolTokenOrcl_ != address(0), systemCoinOrcl_ != address(0)), accountingEngine_ != address(0)), "DebtAuctionInitialParameterSetter/invalid-contract-address");
require(updateDelay_ > 0, "DebtAuctionInitialParameterSetter/null-update-delay");
require(bidTargetValue_ >= HUNDRED, "DebtAuctionInitialParameterSetter/invalid-bid-target-value");
protocolTokenOrcl = OracleLike(protocolTokenOrcl_);
systemCoinOrcl = OracleLike(systemCoinOrcl_);
accountingEngine = AccountingEngineLike(accountingEngine_);
minProtocolTokenAmountOffered = minProtocolTokenAmountOffered_;
protocolTokenPremium = protocolTokenPremium_;
updateDelay = updateDelay_;
bidTargetValue = bidTargetValue_;
bidValueTargetInflation = 0;
bidValueInflationDelay = uint(-1) / 10;
bidValueLastInflationUpdateTime = now;
emit ModifyParameters(bytes32("protocolTokenOrcl"), protocolTokenOrcl_);
emit ModifyParameters(bytes32("systemCoinOrcl"), systemCoinOrcl_);
emit ModifyParameters(bytes32("accountingEngine"), accountingEngine_);
emit ModifyParameters(bytes32("bidTargetValue"), bidTargetValue);
emit ModifyParameters(bytes32("minProtocolTokenAmountOffered"), minProtocolTokenAmountOffered);
emit ModifyParameters(bytes32("protocolTokenPremium"), protocolTokenPremium);
emit ModifyParameters(bytes32("updateDelay"), updateDelay);
}
// --- Boolean Logic ---
function both(bool x, bool y) internal pure returns (bool z) {
assembly{ z := and(x, y)}
}
// --- Math ---
uint internal constant HUNDRED = 100;
uint internal constant THOUSAND = 10 ** 3;
function divide(uint256 x, uint256 y) internal pure returns (uint256 z) {
require(y > 0, "divide-null-y");
z = x / y;
require(z <= x);
}
function rpower(uint256 x, uint256 n) internal pure returns (uint256 z) {
z = n % 2 != 0 ? x : RAY;
for (n /= 2; n != 0; n /= 2) {
x = rmultiply(x, x);
if (n % 2 != 0) {
z = rmultiply(z, x);
}
}
}
// --- Administration ---
/*
* @notice Modify the address of a contract integrated with this setter
* @param parameter Name of the contract to set a new address for
* @param addr The new address
*/
function modifyParameters(bytes32 parameter, address addr) external isAuthorized {
require(addr != address(0), "DebtAuctionInitialParameterSetter/null-addr");
if (parameter == "protocolTokenOrcl") protocolTokenOrcl = OracleLike(addr);
else if (parameter == "systemCoinOrcl") systemCoinOrcl = OracleLike(addr);
else if (parameter == "accountingEngine") accountingEngine = AccountingEngineLike(addr);
else if (parameter == "treasury") {
require(StabilityFeeTreasuryLike(addr).systemCoin() != address(0), "DebtAuctionInitialParameterSetter/treasury-coin-not-set");
treasury = StabilityFeeTreasuryLike(addr);
}
else revert("DebtAuctionInitialParameterSetter/modify-unrecognized-param");
emit ModifyParameters(parameter, addr);
}
/*
* @notice Modify a uint256 parameter
* @param parameter Name of the parameter
* @param addr The new parameter value
*/
function modifyParameters(bytes32 parameter, uint256 val) external isAuthorized {
if (parameter == "minProtocolTokenAmountOffered") {
require(val > 0, "DebtAuctionInitialParameterSetter/null-min-prot-amt");
minProtocolTokenAmountOffered = val;
}
else if (parameter == "protocolTokenPremium") {
require(val < THOUSAND, "DebtAuctionInitialParameterSetter/invalid-prot-token-premium");
protocolTokenPremium = val;
}
else if (parameter == "baseUpdateCallerReward") {
require(val <= maxUpdateCallerReward, "DebtAuctionInitialParameterSetter/invalid-base-caller-reward");
baseUpdateCallerReward = val;
}
else if (parameter == "maxUpdateCallerReward") {
require(val >= baseUpdateCallerReward, "DebtAuctionInitialParameterSetter/invalid-max-reward");
maxUpdateCallerReward = val;
}
else if (parameter == "perSecondCallerRewardIncrease") {
require(val >= RAY, "DebtAuctionInitialParameterSetter/invalid-reward-increase");
perSecondCallerRewardIncrease = val;
}
else if (parameter == "maxRewardIncreaseDelay") {
require(val > 0, "DebtAuctionInitialParameterSetter/invalid-max-increase-delay");
maxRewardIncreaseDelay = val;
}
else if (parameter == "updateDelay") {
require(val > 0, "DebtAuctionInitialParameterSetter/null-update-delay");
updateDelay = val;
}
else if (parameter == "bidTargetValue") {
require(val >= HUNDRED, "DebtAuctionInitialParameterSetter/invalid-bid-target-value");
bidTargetValue = val;
}
else if (parameter == "lastUpdateTime") {
require(val > now, "DebtAuctionInitialParameterSetter/invalid-last-update-time");
lastUpdateTime = val;
}
else if (parameter == "bidValueLastInflationUpdateTime") {
require(both(val >= bidValueLastInflationUpdateTime, val <= now), "DebtAuctionInitialParameterSetter/invalid-bid-inflation-update-time");
bidValueLastInflationUpdateTime = val;
}
else if (parameter == "bidValueInflationDelay") {
require(val <= uint(-1) / 10, "DebtAuctionInitialParameterSetter/invalid-inflation-delay");
bidValueInflationDelay = val;
}
else if (parameter == "bidValueTargetInflation") {
require(val <= MAX_INFLATION, "DebtAuctionInitialParameterSetter/invalid-target-inflation");
bidValueTargetInflation = val;
}
else revert("DebtAuctionInitialParameterSetter/modify-unrecognized-param");
emit ModifyParameters(parameter, val);
}
// --- Setter ---
/*
* @notify View function that returns the new, initial debt auction bid
* @returns debtAuctionBidSize The new, initial debt auction bid
*/
function getNewDebtBid() external view returns (uint256 debtAuctionBidSize) {
// Get token price
(uint256 systemCoinPrice, bool validSysCoinPrice) = systemCoinOrcl.getResultWithValidity();
require(both(systemCoinPrice > 0, validSysCoinPrice), "DebtAuctionInitialParameterSetter/invalid-price");
// Compute the bid size
(, uint256 latestTargetValue) = getNewBidTargetValue();
debtAuctionBidSize = divide(multiply(multiply(latestTargetValue, WAD), RAY), systemCoinPrice);
if (debtAuctionBidSize < RAY) {
debtAuctionBidSize = RAY;
}
}
/*
* @notify View function that returns the initial amount of protocol tokens which should be offered in a debt auction
* @returns debtAuctionMintedTokens The initial amount of protocol tokens that should be offered in a debt auction
*/
function getRawProtocolTokenAmount() external view returns (uint256 debtAuctionMintedTokens) {
// Get token price
(uint256 protocolTknPrice, bool validProtocolPrice) = protocolTokenOrcl.getResultWithValidity();
require(both(validProtocolPrice, protocolTknPrice > 0), "DebtAuctionInitialParameterSetter/invalid-price");
// Compute the amont of protocol tokens without the premium
(, uint256 latestTargetValue) = getNewBidTargetValue();
debtAuctionMintedTokens = divide(multiply(latestTargetValue, WAD), protocolTknPrice);
// Take into account the minimum amount of protocol tokens to offer
if (debtAuctionMintedTokens < minProtocolTokenAmountOffered) {
debtAuctionMintedTokens = minProtocolTokenAmountOffered;
}
}
/*
* @notify View function that returns the initial amount of protocol tokens with a premium added on top
* @returns debtAuctionMintedTokens The initial amount of protocol tokens with a premium added on top
*/
function getPremiumAdjustedProtocolTokenAmount() external view returns (uint256 debtAuctionMintedTokens) {
// Get token price
(uint256 protocolTknPrice, bool validProtocolPrice) = protocolTokenOrcl.getResultWithValidity();
require(both(validProtocolPrice, protocolTknPrice > 0), "DebtAuctionInitialParameterSetter/invalid-price");
// Compute the amont of protocol tokens without the premium and apply it
(, uint256 latestTargetValue) = getNewBidTargetValue();
debtAuctionMintedTokens = divide(
multiply(divide(multiply(latestTargetValue, WAD), protocolTknPrice), protocolTokenPremium), THOUSAND
);
// Take into account the minimum amount of protocol tokens to offer
if (debtAuctionMintedTokens < minProtocolTokenAmountOffered) {
debtAuctionMintedTokens = minProtocolTokenAmountOffered;
}
}
/*
* @notify Set the new debtAuctionBidSize and initialDebtAuctionMintedTokens inside the AccountingEngine
* @param feeReceiver The address that will receive the reward for setting new params
*/
function setDebtAuctionInitialParameters(address feeReceiver) external {
// Check delay between calls
require(either(subtract(now, lastUpdateTime) >= updateDelay, lastUpdateTime == 0), "DebtAuctionInitialParameterSetter/wait-more");
// Get the caller's reward
uint256 callerReward = getCallerReward(lastUpdateTime, updateDelay);
// Store the timestamp of the update
lastUpdateTime = now;
// Get token prices
(uint256 protocolTknPrice, bool validProtocolPrice) = protocolTokenOrcl.getResultWithValidity();
(uint256 systemCoinPrice, bool validSysCoinPrice) = systemCoinOrcl.getResultWithValidity();
require(both(validProtocolPrice, validSysCoinPrice), "DebtAuctionInitialParameterSetter/invalid-prices");
require(both(protocolTknPrice > 0, systemCoinPrice > 0), "DebtAuctionInitialParameterSetter/null-prices");
// Compute the scaled bid target value
uint256 updateSlots;
(updateSlots, bidTargetValue) = getNewBidTargetValue();
bidValueLastInflationUpdateTime = addition(bidValueLastInflationUpdateTime, multiply(updateSlots, bidValueInflationDelay));
uint256 scaledBidTargetValue = multiply(bidTargetValue, WAD);
// Compute the amont of protocol tokens without the premium
uint256 initialDebtAuctionMintedTokens = divide(scaledBidTargetValue, protocolTknPrice);
// Apply the premium
initialDebtAuctionMintedTokens = divide(multiply(initialDebtAuctionMintedTokens, protocolTokenPremium), THOUSAND);
// Take into account the minimum amount of protocol tokens to offer
if (initialDebtAuctionMintedTokens < minProtocolTokenAmountOffered) {
initialDebtAuctionMintedTokens = minProtocolTokenAmountOffered;
}
// Compute the debtAuctionBidSize as a RAD taking into account the minimum amount to bid
uint256 debtAuctionBidSize = divide(multiply(scaledBidTargetValue, RAY), systemCoinPrice);
if (debtAuctionBidSize < RAY) {
debtAuctionBidSize = RAY;
}
// Set the debt bid and the associated protocol token amount in the accounting engine
accountingEngine.modifyParameters("debtAuctionBidSize", debtAuctionBidSize);
accountingEngine.modifyParameters("initialDebtAuctionMintedTokens", initialDebtAuctionMintedTokens);
// Emit an event
emit SetDebtAuctionInitialParameters(debtAuctionBidSize, initialDebtAuctionMintedTokens);
// Pay the caller for updating the rate
rewardCaller(feeReceiver, callerReward);
}
/*
* @notice Manually set initial debt auction parameters
* @param debtAuctionBidSize The initial debt auction bid size
* @param initialDebtAuctionMintedTokens The initial amount of protocol tokens to mint in exchange for debtAuctionBidSize system coins
*/
function manualSetDebtAuctionParameters(uint256 debtAuctionBidSize, uint256 initialDebtAuctionMintedTokens)
external isAuthorized {
accountingEngine.modifyParameters("debtAuctionBidSize", debtAuctionBidSize);
accountingEngine.modifyParameters("initialDebtAuctionMintedTokens", initialDebtAuctionMintedTokens);
emit SetDebtAuctionInitialParameters(debtAuctionBidSize, initialDebtAuctionMintedTokens);
}
// --- Internal Logic ---
/*
* @notice Return the latest bidTargetValue
*/
function getNewBidTargetValue() internal view returns (uint256, uint256) {
uint256 updateSlots = subtract(now, bidValueLastInflationUpdateTime) / bidValueInflationDelay;
if (updateSlots == 0) return (0, bidTargetValue);
uint256 targetValue = bidTargetValue;
for (uint i = 0; i < updateSlots; i++) {
targetValue = addition(targetValue, multiply(targetValue / HUNDRED, bidValueTargetInflation));
}
return (
updateSlots,
targetValue
);
}
}
{
"compilationTarget": {
"DebtAuctionInitialParameterSetter.sol": "DebtAuctionInitialParameterSetter"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"protocolTokenOrcl_","type":"address"},{"internalType":"address","name":"systemCoinOrcl_","type":"address"},{"internalType":"address","name":"accountingEngine_","type":"address"},{"internalType":"address","name":"treasury_","type":"address"},{"internalType":"uint256","name":"updateDelay_","type":"uint256"},{"internalType":"uint256","name":"baseUpdateCallerReward_","type":"uint256"},{"internalType":"uint256","name":"maxUpdateCallerReward_","type":"uint256"},{"internalType":"uint256","name":"perSecondCallerRewardIncrease_","type":"uint256"},{"internalType":"uint256","name":"minProtocolTokenAmountOffered_","type":"uint256"},{"internalType":"uint256","name":"protocolTokenPremium_","type":"uint256"},{"internalType":"uint256","name":"bidTargetValue_","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"AddAuthorization","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes","name":"revertReason","type":"bytes"},{"indexed":false,"internalType":"address","name":"feeReceiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"FailRewardCaller","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"parameter","type":"bytes32"},{"indexed":false,"internalType":"address","name":"addr","type":"address"}],"name":"ModifyParameters","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"parameter","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"val","type":"uint256"}],"name":"ModifyParameters","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"RemoveAuthorization","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"debtAuctionBidSize","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"initialDebtAuctionMintedTokens","type":"uint256"}],"name":"SetDebtAuctionInitialParameters","type":"event"},{"inputs":[],"name":"MAX_INFLATION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WAD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"accountingEngine","outputs":[{"internalType":"contract AccountingEngineLike","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"name":"addition","outputs":[{"internalType":"uint256","name":"z","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"authorizedAccounts","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseUpdateCallerReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bidTargetValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bidValueInflationDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bidValueLastInflationUpdateTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bidValueTargetInflation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"timeOfLastUpdate","type":"uint256"},{"internalType":"uint256","name":"defaultDelayBetweenCalls","type":"uint256"}],"name":"getCallerReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNewDebtBid","outputs":[{"internalType":"uint256","name":"debtAuctionBidSize","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPremiumAdjustedProtocolTokenAmount","outputs":[{"internalType":"uint256","name":"debtAuctionMintedTokens","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRawProtocolTokenAmount","outputs":[{"internalType":"uint256","name":"debtAuctionMintedTokens","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastUpdateTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"debtAuctionBidSize","type":"uint256"},{"internalType":"uint256","name":"initialDebtAuctionMintedTokens","type":"uint256"}],"name":"manualSetDebtAuctionParameters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maxRewardIncreaseDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxUpdateCallerReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minProtocolTokenAmountOffered","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"name":"minimum","outputs":[{"internalType":"uint256","name":"z","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"parameter","type":"bytes32"},{"internalType":"address","name":"addr","type":"address"}],"name":"modifyParameters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"parameter","type":"bytes32"},{"internalType":"uint256","name":"val","type":"uint256"}],"name":"modifyParameters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"name":"multiply","outputs":[{"internalType":"uint256","name":"z","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"perSecondCallerRewardIncrease","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolTokenOrcl","outputs":[{"internalType":"contract OracleLike","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolTokenPremium","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"}],"name":"rad","outputs":[{"internalType":"uint256","name":"z","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"}],"name":"ray","outputs":[{"internalType":"uint256","name":"z","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"name":"rdivide","outputs":[{"internalType":"uint256","name":"z","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"removeAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"name":"rmultiply","outputs":[{"internalType":"uint256","name":"z","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"n","type":"uint256"},{"internalType":"uint256","name":"base","type":"uint256"}],"name":"rpower","outputs":[{"internalType":"uint256","name":"z","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"feeReceiver","type":"address"}],"name":"setDebtAuctionInitialParameters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"name":"subtract","outputs":[{"internalType":"uint256","name":"z","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"systemCoinOrcl","outputs":[{"internalType":"contract OracleLike","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"contract StabilityFeeTreasuryLike","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasuryAllowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"updateDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"name":"wdivide","outputs":[{"internalType":"uint256","name":"z","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"name":"wmultiply","outputs":[{"internalType":"uint256","name":"z","type":"uint256"}],"stateMutability":"pure","type":"function"}]