Address Contract Partially Verified
Address
0xCb170bc873b3a1F69F433C25a4b6d0fd4D4D90De
Balance
0 ETH
Nonce
1
Code Size
8141 bytes
Creator
Create2 Deployer at tx 0x4339ee4b...95f498
Indexed Transactions
0 (1 on-chain, 0.8% indexed)
Contract Bytecode
8141 bytes
0x60806040526004361015610011575f80fd5b5f3560e01c80630f3482f4146110a65780631438291d14610ffe5780631ec01d7114610f9657806322f3e2d414610f575780633f4ba83a14610ebb5780634eeda9b314610e6e57806350c1d19d14610dc85780635c975abb14610d885780636ab79e5514610cc3578063715018a614610c0157806373ad494614610a4d57806374bd94ca146109b557806379231b55146108da57806379502c5514610879578063797ed3391461081157806379ba5097146107095780637e6561d1146106c25780638456cb59146106235780638da5cb5b146105d357806395453b991461056e578063995be491146105335780639d9b879f146104ec578063a69fe86314610495578063addeec05146103c2578063c3f909d41461035d578063c4b97370146102a5578063d604b6f31461026a578063e30c3978146102195763f2fde38b14610158575f80fd5b346102155760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102155773ffffffffffffffffffffffffffffffffffffffff6101a46110e6565b6101ac611e21565b16807fffffffffffffffffffffffff0000000000000000000000000000000000000000600154161760015573ffffffffffffffffffffffffffffffffffffffff5f54167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e227005f80a3005b5f80fd5b34610215575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021557602073ffffffffffffffffffffffffffffffffffffffff60015416604051908152f35b34610215575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610215576020600654604051908152f35b34610215575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102155760405180602060085491828152019060085f527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3905f5b8181106103315761032d8561032181870382611445565b6040519182918261115e565b0390f35b825473ffffffffffffffffffffffffffffffffffffffff1684526020909301926001928301920161030a565b34610215575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610215576002546040805167ffffffffffffffff8316815265ffffffffffff83831c8116602083015260709390931c90921690820152606090f35b346102155760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102155773ffffffffffffffffffffffffffffffffffffffff61040e6110e6565b165f52600360205265ffffffffffff60405f2061032d61047360405192610434846113fc565b54926bffffffffffffffffffffffff841681526bffffffffffffffffffffffff8460601c16602082015284604082019460c01c16845260243590611e41565b9390925116604051938493846040919493926060820195825260208201520152565b34610215576104a336611109565b90335f52600560205260ff60405f205416156104c4576104c292611a6e565b005b7fd16eff2c000000000000000000000000000000000000000000000000000000005f5260045ffd5b346102155760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610215576104c26105266110e6565b61052e611e21565b611970565b34610215575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610215576020600854604051908152f35b346102155760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102155760a06105b36105aa6110e6565b602435906117ed565b926040929192519485526020850152604084015260608301526080820152f35b34610215575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021557602073ffffffffffffffffffffffffffffffffffffffff5f5416604051908152f35b34610215575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021557610659611e21565b60017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00600454161760045573ffffffffffffffffffffffffffffffffffffffff5f54167f1de826ef030779faf6297a59d31edbc7acc6aac614f54b2d0968f27664c8eea25f80a2005b346102155760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610215576104c26106fc6110e6565b610704611e21565b61159a565b34610215575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610215573373ffffffffffffffffffffffffffffffffffffffff60015416036107e5577fffffffffffffffffffffffff0000000000000000000000000000000000000000600154166001555f54337fffffffffffffffffffffffff00000000000000000000000000000000000000008216175f5573ffffffffffffffffffffffffffffffffffffffff3391167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3005b7f118cdaa7000000000000000000000000000000000000000000000000000000005f523360045260245ffd5b346102155760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102155773ffffffffffffffffffffffffffffffffffffffff61085d6110e6565b165f526009602052602060ff60405f2054166040519015158152f35b34610215575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021557606060025465ffffffffffff6040519167ffffffffffffffff81168352818160401c16602084015260701c166040820152f35b346102155760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610215576109116110e6565b7f21a95eed211c23f80e79d231f7abb54e905a054409389ac588fd29be1847e329602073ffffffffffffffffffffffffffffffffffffffff60243593610955611e21565b1692835f526003825260405f206bffffffffffffffffffffffff61098461097f8483855416611486565b611f31565b167fffffffffffffffffffffffffffffffffffffffff000000000000000000000000825416179055604051908152a2005b346102155760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102155773ffffffffffffffffffffffffffffffffffffffff610a016110e6565b165f526003602052606060405f205465ffffffffffff604051916bffffffffffffffffffffffff811683526bffffffffffffffffffffffff81851c16602084015260c01c166040820152f35b346102155760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021557600435602435604435610a8d611e21565b670de0b6b3a76400008311610bd9578215610bd9578115610bd9578015610bd95767ffffffffffffffff8311610ba85791610ba37f6d05db271e19f930af71c4765de54ef86294762644c20f4d6fd2609d057d3c7b9367ffffffffffffffff8316610af785611f85565b6dffffffffffff0000000000000000610b0f84611f85565b92604051610b1c816113fc565b81815265ffffffffffff84166020820152604065ffffffffffff86169101527fffffffffffffffffffffffff000000000000000000000000000000000000000073ffffffffffff00000000000000000000000000006002549560701b169416179160401b161717600255604051938493846040919493926060820195825260208201520152565b0390a1005b827f6dfcc650000000000000000000000000000000000000000000000000000000005f52604060045260245260445ffd5b7f720fefa5000000000000000000000000000000000000000000000000000000005f5260045ffd5b34610215575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021557610c37611e21565b7fffffffffffffffffffffffff0000000000000000000000000000000000000000600154166001555f73ffffffffffffffffffffffffffffffffffffffff81547fffffffffffffffffffffffff000000000000000000000000000000000000000081168355167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b346102155760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102155773ffffffffffffffffffffffffffffffffffffffff610d0f6110e6565b165f52600360205260405f2060405190610d28826113fc565b549061032d60406bffffffffffffffffffffffff84169283815265ffffffffffff6bffffffffffffffffffffffff8660601c169586602084015260c01c169182910152604051938493846040919493926060820195825260208201520152565b34610215575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021557602060ff600454166040519015158152f35b34610215575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102155760e060ff600454161573ffffffffffffffffffffffffffffffffffffffff5f541660025465ffffffffffff6006549160085493604051958652602086015267ffffffffffffffff655af3107a400081831604166040860152818160401c16606086015260701c16608084015260a083015260c0820152f35b346102155760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610215576020610eb3610eaa6110e6565b60243590611493565b604051908152f35b34610215575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021557610ef1611e21565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff006004541660045573ffffffffffffffffffffffffffffffffffffffff5f54167ff1139a912088c5b0ef978063604b9a2861e01877a93e9a784811653c392c93f05f80a2005b34610215575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261021557602060ff6004541615604051908152f35b346102155760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102155773ffffffffffffffffffffffffffffffffffffffff610fe26110e6565b165f526005602052602060ff60405f2054166040519015158152f35b34610215575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102155760405180602060065491828152019060065f527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f905f5b81811061107a5761032d8561032181870382611445565b825473ffffffffffffffffffffffffffffffffffffffff16845260209093019260019283019201611063565b34610215576110b436611109565b919091335f52600560205260ff60405f205416156104c4576040926110d892611211565b825191151582526020820152f35b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361021557565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc60609101126102155760043573ffffffffffffffffffffffffffffffffffffffff8116810361021557906024359060443590565b60206040818301928281528451809452019201905f5b8181106111815750505090565b825173ffffffffffffffffffffffffffffffffffffffff16845260209384019390920191600101611174565b919082039182116111ba57565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b906bffffffffffffffffffffffff809116911603906bffffffffffffffffffffffff82116111ba57565b929160ff600454166113d1576bffffffffffffffffffffffff9073ffffffffffffffffffffffffffffffffffffffff851692835f52600360205261125a8260405f208098611b09565b8554838160601c1693849116016bffffffffffffffffffffffff81116111ba576bffffffffffffffffffffffff16958682116113c7577fa702095f9d030599a017ba3f837aced3a999d4b8bc3d5b426e97fb5d21240d7b9360409361133e92849280841161134f5750611339906112f16bffffffffffffffffffffffff85166bffffffffffffffffffffffff835460601c166111e7565b7fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff77ffffffffffffffffffffffff00000000000000000000000083549260601b169116179055565b6111ad565b82519182526020820152a260019190565b61139a6bffffffffffffffffffffffff61136a8193876111ad565b7fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff855416855516828454166111e7565b167fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008254161790556111ad565b50505050505f9190565b505090506001907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90565b6060810190811067ffffffffffffffff82111761141857604052565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761141857604052565b919082018092116111ba57565b60ff6004541661151a576115179173ffffffffffffffffffffffffffffffffffffffff61151192165f52600360205260405f2065ffffffffffff604051916114da836113fc565b546bffffffffffffffffffffffff811683526bffffffffffffffffffffffff8160601c16602084015260c01c166040820152611e41565b90611486565b90565b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90565b6006548110156115585760065f5260205f2001905f90565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b8054821015611558575f5260205f2001905f90565b73ffffffffffffffffffffffffffffffffffffffff16805f52600560205260ff60405f205416156117a057805f52600560205260405f207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008154169055805f52600760205260405f205480611631575b507f866e298261785517125ac3315911164e21e5df8ff57eacb6b4957ce24109a7a25f80a2565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81018181116111ba576006547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81019081116111ba5780820361172b575b50505060065480156116fe577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016116c781611540565b73ffffffffffffffffffffffffffffffffffffffff82549160031b1b19169055600655805f5260076020525f60408120555f61160a565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffd5b6117609173ffffffffffffffffffffffffffffffffffffffff61175061178c93611540565b90549060031b1c16928391611540565b90919073ffffffffffffffffffffffffffffffffffffffff8084549260031b9316831b921b1916179055565b5f52600760205260405f20555f8080611690565b50565b818102929181159184041417156111ba57565b81156117c0570490565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b90915f915f9060ff600454166119405773ffffffffffffffffffffffffffffffffffffffff165f52600360205260405f209165ffffffffffff60405193611833856113fc565b546bffffffffffffffffffffffff811685526bffffffffffffffffffffffff8160601c16602086015260c01c16604084015261189060025495670de0b6b3a764000061188967ffffffffffffffff8916836117a3565b0494611e41565b9590869185151580611907575b90869182841090816118ff575b506118c4575b5050906118bc91611486565b939493929190565b829550906118ef6118f49265ffffffffffff6118e46118bc9796856111ad565b9160401c16906117a3565b6117b6565b93909150845f6118b0565b90505f6118aa565b9650915061191581866111ad565b61271081029080820461271014901517156111ba5787926119378780936117b6565b9790915061189d565b505f93507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff925082918291508490565b73ffffffffffffffffffffffffffffffffffffffff8116908115611a4657815f52600560205260ff60405f205416611a4257815f52600560205260405f2060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00825416179055600654600181018091116111ba57825f52600760205260405f2055600654906801000000000000000082101561141857611760826001611a1c94016006556006611585565b7f0d157ae202c20e2b2ce3276e8eadcade3d0bb54d44f457cd139221fe5f08c0875f80a2565b5050565b7fb481fd03000000000000000000000000000000000000000000000000000000005f5260045ffd5b9160ff60045416611b045781611af77f4266037b3b3b6e7a013c1c080a864cd905509bd354f8ad4a141605bae9d81e4393604093611af273ffffffffffffffffffffffffffffffffffffffff881697885f526003602052611ad383885f208093611b09565b6112f161097f856bffffffffffffffffffffffff845460601c16611486565b611486565b82519182526020820152a2565b505050565b9165ffffffffffff825460c01c1692670de0b6b3a7640000611b42611b2e86426111ad565b9367ffffffffffffffff60025416906117a3565b049315611ce757508015611b04576bffffffffffffffffffffffff611ba3611cc094611b95611b8c65ffffffffffff60025460401c168087115f14611cde576118ef815b856117a3565b84875416611486565b80821015611cd75750611f31565b167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000083541617825565ffffffffffff60025460701c16908181115f14611ccd5750611c06815b6118ef6bffffffffffffffffffffffff855460601c1693846117a3565b80821115611cc257611c73916bffffffffffffffffffffffff611c2a9216906111e7565b82547fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff1660609190911b77ffffffffffffffffffffffff00000000000000000000000016178255565b80547fffff000000000000ffffffffffffffffffffffffffffffffffffffffffffffff164260c01b7dffffffffffff00000000000000000000000000000000000000000000000016179055565b565b5050611c735f611c2a565b611c069091611be9565b9050611f31565b6118ef87611b86565b905073ffffffffffffffffffffffffffffffffffffffff8116805f52600960205260ff60405f20541615611da7575b50506bffffffffffffffffffffffff611d31611cc093611f31565b82547dffffffffffff0000000000000000000000000000000000000000000000004260c01b167fffff000000000000000000000000000000000000000000000000000000000000909116919092167fffff000000000000000000000000000000000000ffffffffffffffffffffffff1617179055565b5f52600960205260405f2060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00825416179055600854906801000000000000000082101561141857611cc093611e1a611d31926117608560016bffffffffffffffffffffffff97016008556008611585565b9350611d16565b73ffffffffffffffffffffffffffffffffffffffff5f541633036107e557565b919091670de0b6b3a7640000611e656002549467ffffffffffffffff8616906117a3565b0465ffffffffffff6040830151168015611f28576bffffffffffffffffffffffff9165ffffffffffff611e9b611ef093426111ad565b91611ec4611ebb838a60401c168086115f14611f1f576118ef81856117a3565b86885116611486565b80821015611f175750965b60701c169081811115611f0b57506118ef602082955b0194848651166117a3565b9151169080821115611f0557611517916111ad565b50505f90565b60206118ef9195611ee5565b905096611ecf565b6118ef86611b86565b5092505f919050565b6bffffffffffffffffffffffff8111611f55576bffffffffffffffffffffffff1690565b7f6dfcc650000000000000000000000000000000000000000000000000000000005f52606060045260245260445ffd5b65ffffffffffff8111611f9d5765ffffffffffff1690565b7f6dfcc650000000000000000000000000000000000000000000000000000000005f52603060045260245260445ffd
Verified Source Code Partial Match
Compiler: v0.8.30+commit.73712a01
EVM: cancun
Optimization: Yes (999999 runs)
CircuitBreaker.sol 535 lines
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.30;
import {ICircuitBreaker} from "../interfaces/ICircuitBreaker.sol";
import {Ownable2Step, Ownable} from "@openzeppelin/contracts/access/Ownable2Step.sol";
import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
/// @title CircuitBreaker
/// @notice Rate limiter implementing dual buffer system (ERC-7265 inspired)
/// @dev Uses main buffer (time-replenishing) + elastic buffer (deposit-tracking) to prevent flashloan DoS
contract CircuitBreaker is ICircuitBreaker, Ownable2Step {
using SafeCast for uint256;
// ============ Structs ============
/// @notice Configuration for rate limiting (packed into 1 slot)
struct LimiterConfig {
uint64 maxDrawRateWad; // Maximum withdrawal rate as WAD (1e18 = 100%), max ~18.4e18
uint48 mainWindow; // Time for main buffer to fully replenish (seconds), max ~8.9M years
uint48 elasticWindow; // Time for elastic buffer to decay to zero (seconds)
}
/// @notice State tracking for an asset's rate limiter (packed into 1 slot)
struct LimiterState {
uint96 mainBuffer; // Current main buffer capacity, max ~7.9e28
uint96 elasticBuffer; // Current elastic buffer capacity
uint48 lastUpdate; // Timestamp of last state update
}
// ============ State Variables ============
/// @notice Global rate limiting configuration
LimiterConfig public config;
/// @notice Per-asset rate limiter state
mapping(address asset => LimiterState state) public assetState;
/// @notice Whether the circuit breaker is paused (allows all transactions)
bool public paused;
/// @notice Whitelist of addresses allowed to call recordInflow/checkAndRecordOutflow
mapping(address => bool) public protectedContracts;
/// @notice Array of protected contracts for enumeration
address[] internal _protectedContractList;
/// @notice Index tracking for O(1) removal from protected contract list
mapping(address => uint256) internal _protectedContractIndex;
/// @notice Array of assets with tracked state for enumeration
address[] internal _trackedAssets;
/// @notice Whether an asset is already in the tracked list
mapping(address => bool) public isTrackedAsset;
// ============ Errors ============
error CircuitBreakerInvalidConfig();
error CircuitBreakerZeroAddress();
error CircuitBreakerNotProtectedContract();
// ============ Events ============
event ProtectedContractAdded(address indexed protectedContract);
event ProtectedContractRemoved(address indexed protectedContract);
// ============ Modifiers ============
modifier onlyProtectedContract() {
if (!protectedContracts[msg.sender]) revert CircuitBreakerNotProtectedContract();
_;
}
// ============ Constructor ============
/// @notice Initialize circuit breaker with configuration
/// @param maxDrawRateWad Maximum withdrawal rate as WAD (1e18 = 100%)
/// @param mainWindow Time for main buffer to fully replenish (seconds)
/// @param elasticWindow Time for elastic buffer to decay (seconds)
/// @param initialOwner Address that will own the CircuitBreaker
constructor(
uint256 maxDrawRateWad,
uint256 mainWindow,
uint256 elasticWindow,
address initialOwner
)
Ownable(initialOwner)
{
_updateConfig(maxDrawRateWad, mainWindow, elasticWindow);
paused = false;
}
// ============ Core Functions ============
/// @inheritdoc ICircuitBreaker
function recordInflow(
address asset,
uint256 amount,
uint256 preTvl
)
external
onlyProtectedContract
{
// If paused, don't track inflows (state frozen)
if (paused) {
return;
}
LimiterState storage state = assetState[asset];
// Update buffers with time decay/replenishment before processing inflow
_updateBuffers(asset, state, preTvl);
// Increase elastic buffer by deposit amount
state.elasticBuffer = (uint256(state.elasticBuffer) + amount).toUint96();
emit Inflow(asset, amount, preTvl + amount);
}
/// @inheritdoc ICircuitBreaker
function checkAndRecordOutflow(
address asset,
uint256 amount,
uint256 preTvl
)
external
onlyProtectedContract
returns (bool allowed, uint256 available)
{
// If paused, allow all withdrawals
if (paused) {
return (true, type(uint256).max);
}
LimiterState storage state = assetState[asset];
// Update buffers with time decay/replenishment
_updateBuffers(asset, state, preTvl);
// Calculate total available capacity
available = state.mainBuffer + state.elasticBuffer;
// Check if withdrawal fits within capacity
if (amount <= available) {
// Deduct from elastic buffer first, then main buffer
if (amount <= state.elasticBuffer) {
state.elasticBuffer -= uint96(amount);
} else {
uint256 remainingAfterElastic = amount - state.elasticBuffer;
state.elasticBuffer = 0;
state.mainBuffer -= uint96(remainingAfterElastic);
}
emit Outflow(asset, amount, preTvl - amount);
return (true, available);
} else {
// Rate limit exceeded - wrapper will revert
return (false, available);
}
}
// ============ View Functions ============
/// @inheritdoc ICircuitBreaker
function withdrawalCapacity(
address asset,
uint256 currentTvl
)
external
view
returns (uint256 capacity)
{
if (paused) {
return type(uint256).max;
}
LimiterState memory state = assetState[asset];
// Simulate buffer updates without modifying state
(uint256 mainBuffer, uint256 elasticBuffer) = _calculateBuffers(state, currentTvl);
return mainBuffer + elasticBuffer;
}
/// @inheritdoc ICircuitBreaker
function isActive() external view returns (bool active) {
return !paused;
}
/// @notice Get the current configuration
/// @return maxDrawRateWad Maximum withdrawal rate as WAD
/// @return mainWindow Time for main buffer to fully replenish
/// @return elasticWindow Time for elastic buffer to decay
function getConfig()
external
view
returns (uint256 maxDrawRateWad, uint256 mainWindow, uint256 elasticWindow)
{
return (config.maxDrawRateWad, config.mainWindow, config.elasticWindow);
}
/// @notice Get the current state for an asset (with time-adjusted values)
/// @param asset The asset to query
/// @param currentTvl The current TVL for accurate buffer calculation
/// @return mainBuffer Current main buffer capacity
/// @return elasticBuffer Current elastic buffer capacity
/// @return lastUpdate Timestamp of last state update
function getAssetState(
address asset,
uint256 currentTvl
)
external
view
returns (uint256 mainBuffer, uint256 elasticBuffer, uint256 lastUpdate)
{
LimiterState memory state = assetState[asset];
(mainBuffer, elasticBuffer) = _calculateBuffers(state, currentTvl);
return (mainBuffer, elasticBuffer, state.lastUpdate);
}
/// @notice Get raw asset state without time adjustments (for debugging)
/// @param asset The asset to query
function getRawAssetState(address asset)
external
view
returns (uint256 mainBuffer, uint256 elasticBuffer, uint256 lastUpdate)
{
LimiterState memory state = assetState[asset];
return (state.mainBuffer, state.elasticBuffer, state.lastUpdate);
}
// ============ Enumeration View Functions ============
/// @notice Get all protected contracts
/// @return contracts Array of protected contract addresses
function getProtectedContracts() external view returns (address[] memory contracts) {
return _protectedContractList;
}
/// @notice Get count of protected contracts
/// @return count Number of protected contracts
function protectedContractCount() external view returns (uint256 count) {
return _protectedContractList.length;
}
/// @notice Get all tracked assets (assets that have had inflows/outflows recorded)
/// @return assets Array of tracked asset addresses
function getTrackedAssets() external view returns (address[] memory assets) {
return _trackedAssets;
}
/// @notice Get count of tracked assets
/// @return count Number of tracked assets
function trackedAssetCount() external view returns (uint256 count) {
return _trackedAssets.length;
}
// ============ Monitoring View Functions ============
/// @notice Get health metrics for an asset (for status page display)
/// @param asset The asset to query
/// @param currentTvl The current TVL for accurate calculations
/// @return mainUtilizationBps Main buffer usage in basis points (0 = full capacity, 10000 = depleted)
/// @return elasticBuffer Current elastic buffer amount
/// @return totalCapacity Total withdrawal capacity available now
/// @return maxCapacity Maximum possible capacity (cap when fully replenished)
/// @return secondsUntilFullReplenishment Estimated seconds until main buffer fully replenishes (0 if full)
function getAssetHealth(
address asset,
uint256 currentTvl
)
external
view
returns (
uint256 mainUtilizationBps,
uint256 elasticBuffer,
uint256 totalCapacity,
uint256 maxCapacity,
uint256 secondsUntilFullReplenishment
)
{
if (paused) {
return (0, type(uint256).max, type(uint256).max, type(uint256).max, 0);
}
LimiterState memory state = assetState[asset];
uint256 cap = (currentTvl * config.maxDrawRateWad) / 1e18;
(uint256 mainBuffer, uint256 elastic) = _calculateBuffers(state, currentTvl);
// Main utilization in basis points: 0 = full capacity, 10000 = fully depleted
if (cap > 0) {
mainUtilizationBps = ((cap - mainBuffer) * 10000) / cap;
}
// Time until full replenishment
if (mainBuffer < cap && cap > 0) {
uint256 deficit = cap - mainBuffer;
// replenishment rate = cap / mainWindow, so time = deficit * mainWindow / cap
secondsUntilFullReplenishment = (deficit * config.mainWindow) / cap;
}
return
(mainUtilizationBps, elastic, mainBuffer + elastic, cap, secondsUntilFullReplenishment);
}
/// @notice Get comprehensive system status for monitoring dashboards
/// @return active Whether circuit breaker is active (not paused)
/// @return adminAddr Current admin address
/// @return maxDrawRateBps Max draw rate in basis points (e.g., 500 = 5%)
/// @return mainWindowSecs Main window in seconds
/// @return elasticWindowSecs Elastic window in seconds
/// @return numProtectedContracts Number of registered protected contracts
/// @return numTrackedAssets Number of assets with recorded state
function getSystemStatus()
external
view
returns (
bool active,
address adminAddr,
uint256 maxDrawRateBps,
uint256 mainWindowSecs,
uint256 elasticWindowSecs,
uint256 numProtectedContracts,
uint256 numTrackedAssets
)
{
return (
!paused,
owner(),
config.maxDrawRateWad / 1e14, // Convert WAD to basis points
config.mainWindow,
config.elasticWindow,
_protectedContractList.length,
_trackedAssets.length
);
}
// ============ Admin Functions ============
/// @inheritdoc ICircuitBreaker
function pause() external onlyOwner {
paused = true;
emit CircuitBreakerPaused(owner());
}
/// @inheritdoc ICircuitBreaker
function unpause() external onlyOwner {
paused = false;
emit CircuitBreakerUnpaused(owner());
}
/// @inheritdoc ICircuitBreaker
function updateConfig(
uint256 maxDrawRateWad,
uint256 mainWindow,
uint256 elasticWindow
)
external
onlyOwner
{
_updateConfig(maxDrawRateWad, mainWindow, elasticWindow);
}
/// @inheritdoc ICircuitBreaker
function emergencyOverride(address asset, uint256 amount) external onlyOwner {
LimiterState storage state = assetState[asset];
// Add the amount to main buffer to allow this specific withdrawal
state.mainBuffer = (uint256(state.mainBuffer) + amount).toUint96();
emit EmergencyOverride(asset, amount);
}
/// @notice Register a contract as allowed to call recordInflow/checkAndRecordOutflow
/// @param protectedContract The contract address to register
function addProtectedContract(address protectedContract) external onlyOwner {
if (protectedContract == address(0)) revert CircuitBreakerZeroAddress();
if (protectedContracts[protectedContract]) return; // Already registered
protectedContracts[protectedContract] = true;
// Track index for O(1) removal (index + 1 to distinguish from default 0)
_protectedContractIndex[protectedContract] = _protectedContractList.length + 1;
_protectedContractList.push(protectedContract);
emit ProtectedContractAdded(protectedContract);
}
/// @notice Unregister a contract from calling recordInflow/checkAndRecordOutflow
/// @param protectedContract The contract address to unregister
function removeProtectedContract(address protectedContract) external onlyOwner {
if (!protectedContracts[protectedContract]) return; // Not registered
protectedContracts[protectedContract] = false;
// O(1) removal using swap-and-pop
uint256 indexPlusOne = _protectedContractIndex[protectedContract];
if (indexPlusOne > 0) {
uint256 index = indexPlusOne - 1;
uint256 lastIndex = _protectedContractList.length - 1;
if (index != lastIndex) {
address lastContract = _protectedContractList[lastIndex];
_protectedContractList[index] = lastContract;
_protectedContractIndex[lastContract] = indexPlusOne;
}
_protectedContractList.pop();
delete _protectedContractIndex[protectedContract];
}
emit ProtectedContractRemoved(protectedContract);
}
// ============ Internal Functions ============
/// @notice Validate and set rate limiter configuration
/// @param maxDrawRateWad Maximum withdrawal rate as WAD (1e18 = 100%)
/// @param mainWindow Time for main buffer to fully replenish (seconds)
/// @param elasticWindow Time for elastic buffer to decay (seconds)
function _updateConfig(
uint256 maxDrawRateWad,
uint256 mainWindow,
uint256 elasticWindow
)
private
{
if (maxDrawRateWad > 1e18) revert CircuitBreakerInvalidConfig();
if (maxDrawRateWad == 0) revert CircuitBreakerInvalidConfig();
if (mainWindow == 0) revert CircuitBreakerInvalidConfig();
if (elasticWindow == 0) revert CircuitBreakerInvalidConfig();
config = LimiterConfig({
maxDrawRateWad: maxDrawRateWad.toUint64(),
mainWindow: mainWindow.toUint48(),
elasticWindow: elasticWindow.toUint48()
});
emit ConfigUpdated(maxDrawRateWad, mainWindow, elasticWindow);
}
/// @notice Update buffers based on time elapsed
/// @param asset The asset address (for tracking)
/// @param state The limiter state to update
/// @param currentTvl The current TVL for calculating main buffer cap
function _updateBuffers(
address asset,
LimiterState storage state,
uint256 currentTvl
)
internal
{
uint256 timeElapsed = block.timestamp - state.lastUpdate;
uint256 cap = (currentTvl * config.maxDrawRateWad) / 1e18;
// First interaction or no time has passed
if (state.lastUpdate == 0) {
// Track this asset for enumeration
if (!isTrackedAsset[asset]) {
isTrackedAsset[asset] = true;
_trackedAssets.push(asset);
}
// Initialize: main buffer starts at cap, elastic at 0
state.mainBuffer = cap.toUint96();
state.elasticBuffer = 0;
state.lastUpdate = uint48(block.timestamp);
return;
}
if (timeElapsed == 0) {
return;
}
// Calculate main buffer replenishment
// Cap timeElapsed to mainWindow to prevent overflow
uint256 effectiveTimeMain =
timeElapsed > config.mainWindow ? config.mainWindow : timeElapsed;
uint256 replenishment = (cap * effectiveTimeMain) / config.mainWindow;
state.mainBuffer = _min(cap, uint256(state.mainBuffer) + replenishment).toUint96();
// Calculate elastic buffer decay
// Cap timeElapsed to elasticWindow to prevent overflow
uint256 effectiveTimeElastic =
timeElapsed > config.elasticWindow ? config.elasticWindow : timeElapsed;
uint256 decay = (uint256(state.elasticBuffer) * effectiveTimeElastic) / config.elasticWindow;
state.elasticBuffer = state.elasticBuffer > decay ? state.elasticBuffer - uint96(decay) : 0;
state.lastUpdate = uint48(block.timestamp);
}
/// @notice Calculate buffers without updating state (for view functions)
/// @param state The limiter state to calculate from
/// @param currentTvl The current TVL for calculating main buffer cap
/// @return mainBuffer The calculated main buffer
/// @return elasticBuffer The calculated elastic buffer
function _calculateBuffers(
LimiterState memory state,
uint256 currentTvl
)
internal
view
returns (uint256 mainBuffer, uint256 elasticBuffer)
{
uint256 cap = (currentTvl * config.maxDrawRateWad) / 1e18;
// First interaction
if (state.lastUpdate == 0) {
return (cap, 0);
}
uint256 timeElapsed = block.timestamp - state.lastUpdate;
// Calculate main buffer replenishment
// Cap timeElapsed to mainWindow to prevent overflow
uint256 effectiveTimeMain =
timeElapsed > config.mainWindow ? config.mainWindow : timeElapsed;
uint256 replenishment = (cap * effectiveTimeMain) / config.mainWindow;
mainBuffer = _min(cap, state.mainBuffer + replenishment);
// Calculate elastic buffer decay
// Cap timeElapsed to elasticWindow to prevent overflow
uint256 effectiveTimeElastic =
timeElapsed > config.elasticWindow ? config.elasticWindow : timeElapsed;
uint256 decay = (state.elasticBuffer * effectiveTimeElastic) / config.elasticWindow;
elasticBuffer = state.elasticBuffer > decay ? state.elasticBuffer - decay : 0;
return (mainBuffer, elasticBuffer);
}
/// @notice Return the minimum of two values
function _min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
}
ICircuitBreaker.sol 177 lines
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.30;
/// @title ICircuitBreaker
/// @notice Interface for the optional circuit breaker module
/// @dev Designed for fail-open behavior - all calls should be wrapped in try/catch
interface ICircuitBreaker {
// ============ Events ============
/// @notice Emitted when an inflow (deposit) is recorded
/// @param asset The collateral token address
/// @param amount The amount deposited
/// @param newTvl The TVL after this deposit
event Inflow(address indexed asset, uint256 amount, uint256 newTvl);
/// @notice Emitted when an outflow (withdrawal) is recorded
/// @param asset The collateral token address
/// @param amount The amount withdrawn
/// @param newTvl The TVL after this withdrawal
event Outflow(address indexed asset, uint256 amount, uint256 newTvl);
/// @notice Emitted when a rate limit is triggered
/// @param asset The collateral token address
/// @param requested The amount requested to withdraw
/// @param available The maximum amount available to withdraw
event RateLimitTriggered(address indexed asset, uint256 requested, uint256 available);
/// @notice Emitted when the circuit breaker configuration is updated
/// @param maxDrawRateWad Maximum withdrawal rate as WAD (1e18 = 100%)
/// @param mainWindow Time for main buffer to fully replenish (in seconds)
/// @param elasticWindow Time for elastic buffer to decay (in seconds)
event ConfigUpdated(uint256 maxDrawRateWad, uint256 mainWindow, uint256 elasticWindow);
/// @notice Emitted when the circuit breaker is paused
/// @param by The address that paused the circuit breaker
event CircuitBreakerPaused(address indexed by);
/// @notice Emitted when the circuit breaker is unpaused
/// @param by The address that unpaused the circuit breaker
event CircuitBreakerUnpaused(address indexed by);
/// @notice Emitted when an emergency override is performed
/// @param asset The collateral token address
/// @param amount The amount added to withdrawal capacity
event EmergencyOverride(address indexed asset, uint256 amount);
// ============ Core Functions ============
/// @notice Record an asset inflow (deposit)
/// @dev Called after assets have been transferred in
/// @param asset The collateral token address
/// @param amount The amount deposited
/// @param preTvl The TVL before this deposit
function recordInflow(address asset, uint256 amount, uint256 preTvl) external;
/// @notice Check if outflow is allowed and record it
/// @dev Called before assets are transferred out
/// @param asset The collateral token address
/// @param amount The amount to withdraw
/// @param preTvl The TVL before this withdrawal
/// @return allowed Whether the withdrawal is within rate limits
/// @return available The maximum amount that could be withdrawn
function checkAndRecordOutflow(
address asset,
uint256 amount,
uint256 preTvl
)
external
returns (bool allowed, uint256 available);
// ============ View Functions ============
/// @notice Get the current withdrawal capacity for an asset
/// @param asset The collateral token address
/// @param currentTvl The current TVL
/// @return capacity The maximum amount that can be withdrawn
function withdrawalCapacity(
address asset,
uint256 currentTvl
)
external
view
returns (uint256 capacity);
/// @notice Check if the circuit breaker is currently active (not paused)
/// @return active True if the circuit breaker is active, false if paused
function isActive() external view returns (bool active);
// ============ Monitoring View Functions ============
/// @notice Get all protected contracts
/// @return contracts Array of protected contract addresses
function getProtectedContracts() external view returns (address[] memory contracts);
/// @notice Get count of protected contracts
/// @return count Number of protected contracts
function protectedContractCount() external view returns (uint256 count);
/// @notice Get all tracked assets
/// @return assets Array of tracked asset addresses
function getTrackedAssets() external view returns (address[] memory assets);
/// @notice Get count of tracked assets
/// @return count Number of tracked assets
function trackedAssetCount() external view returns (uint256 count);
/// @notice Get health metrics for an asset
/// @param asset The asset to query
/// @param currentTvl The current TVL
/// @return mainUtilizationBps Main buffer usage in basis points (0 = full, 10000 = depleted)
/// @return elasticBuffer Current elastic buffer amount
/// @return totalCapacity Total withdrawal capacity
/// @return maxCapacity Maximum possible capacity
/// @return secondsUntilFullReplenishment Seconds until main buffer fully replenishes
function getAssetHealth(
address asset,
uint256 currentTvl
)
external
view
returns (
uint256 mainUtilizationBps,
uint256 elasticBuffer,
uint256 totalCapacity,
uint256 maxCapacity,
uint256 secondsUntilFullReplenishment
);
/// @notice Get comprehensive system status
/// @return active Whether circuit breaker is active
/// @return adminAddr Current admin address
/// @return maxDrawRateBps Max draw rate in basis points
/// @return mainWindowSecs Main window in seconds
/// @return elasticWindowSecs Elastic window in seconds
/// @return numProtectedContracts Number of protected contracts
/// @return numTrackedAssets Number of tracked assets
function getSystemStatus()
external
view
returns (
bool active,
address adminAddr,
uint256 maxDrawRateBps,
uint256 mainWindowSecs,
uint256 elasticWindowSecs,
uint256 numProtectedContracts,
uint256 numTrackedAssets
);
// ============ Admin Functions ============
/// @notice Pause the circuit breaker (allows all transactions)
/// @dev Only callable by admin
function pause() external;
/// @notice Unpause the circuit breaker
/// @dev Only callable by admin
function unpause() external;
/// @notice Update rate limiting configuration
/// @dev Only callable by admin
/// @param maxDrawRateWad Maximum withdrawal rate as WAD (1e18 = 100%)
/// @param mainWindow Time for main buffer to fully replenish (in seconds)
/// @param elasticWindow Time for elastic buffer to decay (in seconds)
function updateConfig(
uint256 maxDrawRateWad,
uint256 mainWindow,
uint256 elasticWindow
)
external;
/// @notice Emergency override to allow a specific withdrawal
/// @dev Only callable by admin, for false positive resolution
/// @param asset The collateral token address
/// @param amount The amount to allow for withdrawal
function emergencyOverride(address asset, uint256 amount) external;
}
Ownable2Step.sol 67 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (access/Ownable2Step.sol)
pragma solidity ^0.8.20;
import {Ownable} from "./Ownable.sol";
/**
* @dev Contract module which provides access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* This extension of the {Ownable} contract includes a two-step mechanism to transfer
* ownership, where the new owner must call {acceptOwnership} in order to replace the
* old one. This can help prevent common mistakes, such as transfers of ownership to
* incorrect accounts, or to contracts that are unable to interact with the
* permission system.
*
* The initial owner is specified at deployment time in the constructor for `Ownable`. This
* can later be changed with {transferOwnership} and {acceptOwnership}.
*
* This module is used through inheritance. It will make available all functions
* from parent (Ownable).
*/
abstract contract Ownable2Step is Ownable {
address private _pendingOwner;
event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);
/**
* @dev Returns the address of the pending owner.
*/
function pendingOwner() public view virtual returns (address) {
return _pendingOwner;
}
/**
* @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.
* Can only be called by the current owner.
*
* Setting `newOwner` to the zero address is allowed; this can be used to cancel an initiated ownership transfer.
*/
function transferOwnership(address newOwner) public virtual override onlyOwner {
_pendingOwner = newOwner;
emit OwnershipTransferStarted(owner(), newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual override {
delete _pendingOwner;
super._transferOwnership(newOwner);
}
/**
* @dev The new owner accepts the ownership transfer.
*/
function acceptOwnership() public virtual {
address sender = _msgSender();
if (pendingOwner() != sender) {
revert OwnableUnauthorizedAccount(sender);
}
_transferOwnership(sender);
}
}
SafeCast.sol 1162 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SafeCast.sol)
// This file was procedurally generated from scripts/generate/templates/SafeCast.js.
pragma solidity ^0.8.20;
/**
* @dev Wrappers over Solidity's uintXX/intXX/bool casting operators with added overflow
* checks.
*
* Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
* easily result in undesired exploitation or bugs, since developers usually
* assume that overflows raise errors. `SafeCast` restores this intuition by
* reverting the transaction when such an operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeCast {
/**
* @dev Value doesn't fit in an uint of `bits` size.
*/
error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);
/**
* @dev An int value doesn't fit in an uint of `bits` size.
*/
error SafeCastOverflowedIntToUint(int256 value);
/**
* @dev Value doesn't fit in an int of `bits` size.
*/
error SafeCastOverflowedIntDowncast(uint8 bits, int256 value);
/**
* @dev An uint value doesn't fit in an int of `bits` size.
*/
error SafeCastOverflowedUintToInt(uint256 value);
/**
* @dev Returns the downcasted uint248 from uint256, reverting on
* overflow (when the input is greater than largest uint248).
*
* Counterpart to Solidity's `uint248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*/
function toUint248(uint256 value) internal pure returns (uint248) {
if (value > type(uint248).max) {
revert SafeCastOverflowedUintDowncast(248, value);
}
return uint248(value);
}
/**
* @dev Returns the downcasted uint240 from uint256, reverting on
* overflow (when the input is greater than largest uint240).
*
* Counterpart to Solidity's `uint240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*/
function toUint240(uint256 value) internal pure returns (uint240) {
if (value > type(uint240).max) {
revert SafeCastOverflowedUintDowncast(240, value);
}
return uint240(value);
}
/**
* @dev Returns the downcasted uint232 from uint256, reverting on
* overflow (when the input is greater than largest uint232).
*
* Counterpart to Solidity's `uint232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*/
function toUint232(uint256 value) internal pure returns (uint232) {
if (value > type(uint232).max) {
revert SafeCastOverflowedUintDowncast(232, value);
}
return uint232(value);
}
/**
* @dev Returns the downcasted uint224 from uint256, reverting on
* overflow (when the input is greater than largest uint224).
*
* Counterpart to Solidity's `uint224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*/
function toUint224(uint256 value) internal pure returns (uint224) {
if (value > type(uint224).max) {
revert SafeCastOverflowedUintDowncast(224, value);
}
return uint224(value);
}
/**
* @dev Returns the downcasted uint216 from uint256, reverting on
* overflow (when the input is greater than largest uint216).
*
* Counterpart to Solidity's `uint216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*/
function toUint216(uint256 value) internal pure returns (uint216) {
if (value > type(uint216).max) {
revert SafeCastOverflowedUintDowncast(216, value);
}
return uint216(value);
}
/**
* @dev Returns the downcasted uint208 from uint256, reverting on
* overflow (when the input is greater than largest uint208).
*
* Counterpart to Solidity's `uint208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*/
function toUint208(uint256 value) internal pure returns (uint208) {
if (value > type(uint208).max) {
revert SafeCastOverflowedUintDowncast(208, value);
}
return uint208(value);
}
/**
* @dev Returns the downcasted uint200 from uint256, reverting on
* overflow (when the input is greater than largest uint200).
*
* Counterpart to Solidity's `uint200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*/
function toUint200(uint256 value) internal pure returns (uint200) {
if (value > type(uint200).max) {
revert SafeCastOverflowedUintDowncast(200, value);
}
return uint200(value);
}
/**
* @dev Returns the downcasted uint192 from uint256, reverting on
* overflow (when the input is greater than largest uint192).
*
* Counterpart to Solidity's `uint192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*/
function toUint192(uint256 value) internal pure returns (uint192) {
if (value > type(uint192).max) {
revert SafeCastOverflowedUintDowncast(192, value);
}
return uint192(value);
}
/**
* @dev Returns the downcasted uint184 from uint256, reverting on
* overflow (when the input is greater than largest uint184).
*
* Counterpart to Solidity's `uint184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*/
function toUint184(uint256 value) internal pure returns (uint184) {
if (value > type(uint184).max) {
revert SafeCastOverflowedUintDowncast(184, value);
}
return uint184(value);
}
/**
* @dev Returns the downcasted uint176 from uint256, reverting on
* overflow (when the input is greater than largest uint176).
*
* Counterpart to Solidity's `uint176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*/
function toUint176(uint256 value) internal pure returns (uint176) {
if (value > type(uint176).max) {
revert SafeCastOverflowedUintDowncast(176, value);
}
return uint176(value);
}
/**
* @dev Returns the downcasted uint168 from uint256, reverting on
* overflow (when the input is greater than largest uint168).
*
* Counterpart to Solidity's `uint168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*/
function toUint168(uint256 value) internal pure returns (uint168) {
if (value > type(uint168).max) {
revert SafeCastOverflowedUintDowncast(168, value);
}
return uint168(value);
}
/**
* @dev Returns the downcasted uint160 from uint256, reverting on
* overflow (when the input is greater than largest uint160).
*
* Counterpart to Solidity's `uint160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*/
function toUint160(uint256 value) internal pure returns (uint160) {
if (value > type(uint160).max) {
revert SafeCastOverflowedUintDowncast(160, value);
}
return uint160(value);
}
/**
* @dev Returns the downcasted uint152 from uint256, reverting on
* overflow (when the input is greater than largest uint152).
*
* Counterpart to Solidity's `uint152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*/
function toUint152(uint256 value) internal pure returns (uint152) {
if (value > type(uint152).max) {
revert SafeCastOverflowedUintDowncast(152, value);
}
return uint152(value);
}
/**
* @dev Returns the downcasted uint144 from uint256, reverting on
* overflow (when the input is greater than largest uint144).
*
* Counterpart to Solidity's `uint144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*/
function toUint144(uint256 value) internal pure returns (uint144) {
if (value > type(uint144).max) {
revert SafeCastOverflowedUintDowncast(144, value);
}
return uint144(value);
}
/**
* @dev Returns the downcasted uint136 from uint256, reverting on
* overflow (when the input is greater than largest uint136).
*
* Counterpart to Solidity's `uint136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*/
function toUint136(uint256 value) internal pure returns (uint136) {
if (value > type(uint136).max) {
revert SafeCastOverflowedUintDowncast(136, value);
}
return uint136(value);
}
/**
* @dev Returns the downcasted uint128 from uint256, reverting on
* overflow (when the input is greater than largest uint128).
*
* Counterpart to Solidity's `uint128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*/
function toUint128(uint256 value) internal pure returns (uint128) {
if (value > type(uint128).max) {
revert SafeCastOverflowedUintDowncast(128, value);
}
return uint128(value);
}
/**
* @dev Returns the downcasted uint120 from uint256, reverting on
* overflow (when the input is greater than largest uint120).
*
* Counterpart to Solidity's `uint120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*/
function toUint120(uint256 value) internal pure returns (uint120) {
if (value > type(uint120).max) {
revert SafeCastOverflowedUintDowncast(120, value);
}
return uint120(value);
}
/**
* @dev Returns the downcasted uint112 from uint256, reverting on
* overflow (when the input is greater than largest uint112).
*
* Counterpart to Solidity's `uint112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*/
function toUint112(uint256 value) internal pure returns (uint112) {
if (value > type(uint112).max) {
revert SafeCastOverflowedUintDowncast(112, value);
}
return uint112(value);
}
/**
* @dev Returns the downcasted uint104 from uint256, reverting on
* overflow (when the input is greater than largest uint104).
*
* Counterpart to Solidity's `uint104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*/
function toUint104(uint256 value) internal pure returns (uint104) {
if (value > type(uint104).max) {
revert SafeCastOverflowedUintDowncast(104, value);
}
return uint104(value);
}
/**
* @dev Returns the downcasted uint96 from uint256, reverting on
* overflow (when the input is greater than largest uint96).
*
* Counterpart to Solidity's `uint96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*/
function toUint96(uint256 value) internal pure returns (uint96) {
if (value > type(uint96).max) {
revert SafeCastOverflowedUintDowncast(96, value);
}
return uint96(value);
}
/**
* @dev Returns the downcasted uint88 from uint256, reverting on
* overflow (when the input is greater than largest uint88).
*
* Counterpart to Solidity's `uint88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*/
function toUint88(uint256 value) internal pure returns (uint88) {
if (value > type(uint88).max) {
revert SafeCastOverflowedUintDowncast(88, value);
}
return uint88(value);
}
/**
* @dev Returns the downcasted uint80 from uint256, reverting on
* overflow (when the input is greater than largest uint80).
*
* Counterpart to Solidity's `uint80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*/
function toUint80(uint256 value) internal pure returns (uint80) {
if (value > type(uint80).max) {
revert SafeCastOverflowedUintDowncast(80, value);
}
return uint80(value);
}
/**
* @dev Returns the downcasted uint72 from uint256, reverting on
* overflow (when the input is greater than largest uint72).
*
* Counterpart to Solidity's `uint72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*/
function toUint72(uint256 value) internal pure returns (uint72) {
if (value > type(uint72).max) {
revert SafeCastOverflowedUintDowncast(72, value);
}
return uint72(value);
}
/**
* @dev Returns the downcasted uint64 from uint256, reverting on
* overflow (when the input is greater than largest uint64).
*
* Counterpart to Solidity's `uint64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*/
function toUint64(uint256 value) internal pure returns (uint64) {
if (value > type(uint64).max) {
revert SafeCastOverflowedUintDowncast(64, value);
}
return uint64(value);
}
/**
* @dev Returns the downcasted uint56 from uint256, reverting on
* overflow (when the input is greater than largest uint56).
*
* Counterpart to Solidity's `uint56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*/
function toUint56(uint256 value) internal pure returns (uint56) {
if (value > type(uint56).max) {
revert SafeCastOverflowedUintDowncast(56, value);
}
return uint56(value);
}
/**
* @dev Returns the downcasted uint48 from uint256, reverting on
* overflow (when the input is greater than largest uint48).
*
* Counterpart to Solidity's `uint48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*/
function toUint48(uint256 value) internal pure returns (uint48) {
if (value > type(uint48).max) {
revert SafeCastOverflowedUintDowncast(48, value);
}
return uint48(value);
}
/**
* @dev Returns the downcasted uint40 from uint256, reverting on
* overflow (when the input is greater than largest uint40).
*
* Counterpart to Solidity's `uint40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*/
function toUint40(uint256 value) internal pure returns (uint40) {
if (value > type(uint40).max) {
revert SafeCastOverflowedUintDowncast(40, value);
}
return uint40(value);
}
/**
* @dev Returns the downcasted uint32 from uint256, reverting on
* overflow (when the input is greater than largest uint32).
*
* Counterpart to Solidity's `uint32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*/
function toUint32(uint256 value) internal pure returns (uint32) {
if (value > type(uint32).max) {
revert SafeCastOverflowedUintDowncast(32, value);
}
return uint32(value);
}
/**
* @dev Returns the downcasted uint24 from uint256, reverting on
* overflow (when the input is greater than largest uint24).
*
* Counterpart to Solidity's `uint24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*/
function toUint24(uint256 value) internal pure returns (uint24) {
if (value > type(uint24).max) {
revert SafeCastOverflowedUintDowncast(24, value);
}
return uint24(value);
}
/**
* @dev Returns the downcasted uint16 from uint256, reverting on
* overflow (when the input is greater than largest uint16).
*
* Counterpart to Solidity's `uint16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*/
function toUint16(uint256 value) internal pure returns (uint16) {
if (value > type(uint16).max) {
revert SafeCastOverflowedUintDowncast(16, value);
}
return uint16(value);
}
/**
* @dev Returns the downcasted uint8 from uint256, reverting on
* overflow (when the input is greater than largest uint8).
*
* Counterpart to Solidity's `uint8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*/
function toUint8(uint256 value) internal pure returns (uint8) {
if (value > type(uint8).max) {
revert SafeCastOverflowedUintDowncast(8, value);
}
return uint8(value);
}
/**
* @dev Converts a signed int256 into an unsigned uint256.
*
* Requirements:
*
* - input must be greater than or equal to 0.
*/
function toUint256(int256 value) internal pure returns (uint256) {
if (value < 0) {
revert SafeCastOverflowedIntToUint(value);
}
return uint256(value);
}
/**
* @dev Returns the downcasted int248 from int256, reverting on
* overflow (when the input is less than smallest int248 or
* greater than largest int248).
*
* Counterpart to Solidity's `int248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*/
function toInt248(int256 value) internal pure returns (int248 downcasted) {
downcasted = int248(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(248, value);
}
}
/**
* @dev Returns the downcasted int240 from int256, reverting on
* overflow (when the input is less than smallest int240 or
* greater than largest int240).
*
* Counterpart to Solidity's `int240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*/
function toInt240(int256 value) internal pure returns (int240 downcasted) {
downcasted = int240(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(240, value);
}
}
/**
* @dev Returns the downcasted int232 from int256, reverting on
* overflow (when the input is less than smallest int232 or
* greater than largest int232).
*
* Counterpart to Solidity's `int232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*/
function toInt232(int256 value) internal pure returns (int232 downcasted) {
downcasted = int232(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(232, value);
}
}
/**
* @dev Returns the downcasted int224 from int256, reverting on
* overflow (when the input is less than smallest int224 or
* greater than largest int224).
*
* Counterpart to Solidity's `int224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*/
function toInt224(int256 value) internal pure returns (int224 downcasted) {
downcasted = int224(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(224, value);
}
}
/**
* @dev Returns the downcasted int216 from int256, reverting on
* overflow (when the input is less than smallest int216 or
* greater than largest int216).
*
* Counterpart to Solidity's `int216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*/
function toInt216(int256 value) internal pure returns (int216 downcasted) {
downcasted = int216(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(216, value);
}
}
/**
* @dev Returns the downcasted int208 from int256, reverting on
* overflow (when the input is less than smallest int208 or
* greater than largest int208).
*
* Counterpart to Solidity's `int208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*/
function toInt208(int256 value) internal pure returns (int208 downcasted) {
downcasted = int208(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(208, value);
}
}
/**
* @dev Returns the downcasted int200 from int256, reverting on
* overflow (when the input is less than smallest int200 or
* greater than largest int200).
*
* Counterpart to Solidity's `int200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*/
function toInt200(int256 value) internal pure returns (int200 downcasted) {
downcasted = int200(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(200, value);
}
}
/**
* @dev Returns the downcasted int192 from int256, reverting on
* overflow (when the input is less than smallest int192 or
* greater than largest int192).
*
* Counterpart to Solidity's `int192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*/
function toInt192(int256 value) internal pure returns (int192 downcasted) {
downcasted = int192(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(192, value);
}
}
/**
* @dev Returns the downcasted int184 from int256, reverting on
* overflow (when the input is less than smallest int184 or
* greater than largest int184).
*
* Counterpart to Solidity's `int184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*/
function toInt184(int256 value) internal pure returns (int184 downcasted) {
downcasted = int184(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(184, value);
}
}
/**
* @dev Returns the downcasted int176 from int256, reverting on
* overflow (when the input is less than smallest int176 or
* greater than largest int176).
*
* Counterpart to Solidity's `int176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*/
function toInt176(int256 value) internal pure returns (int176 downcasted) {
downcasted = int176(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(176, value);
}
}
/**
* @dev Returns the downcasted int168 from int256, reverting on
* overflow (when the input is less than smallest int168 or
* greater than largest int168).
*
* Counterpart to Solidity's `int168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*/
function toInt168(int256 value) internal pure returns (int168 downcasted) {
downcasted = int168(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(168, value);
}
}
/**
* @dev Returns the downcasted int160 from int256, reverting on
* overflow (when the input is less than smallest int160 or
* greater than largest int160).
*
* Counterpart to Solidity's `int160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*/
function toInt160(int256 value) internal pure returns (int160 downcasted) {
downcasted = int160(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(160, value);
}
}
/**
* @dev Returns the downcasted int152 from int256, reverting on
* overflow (when the input is less than smallest int152 or
* greater than largest int152).
*
* Counterpart to Solidity's `int152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*/
function toInt152(int256 value) internal pure returns (int152 downcasted) {
downcasted = int152(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(152, value);
}
}
/**
* @dev Returns the downcasted int144 from int256, reverting on
* overflow (when the input is less than smallest int144 or
* greater than largest int144).
*
* Counterpart to Solidity's `int144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*/
function toInt144(int256 value) internal pure returns (int144 downcasted) {
downcasted = int144(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(144, value);
}
}
/**
* @dev Returns the downcasted int136 from int256, reverting on
* overflow (when the input is less than smallest int136 or
* greater than largest int136).
*
* Counterpart to Solidity's `int136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*/
function toInt136(int256 value) internal pure returns (int136 downcasted) {
downcasted = int136(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(136, value);
}
}
/**
* @dev Returns the downcasted int128 from int256, reverting on
* overflow (when the input is less than smallest int128 or
* greater than largest int128).
*
* Counterpart to Solidity's `int128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*/
function toInt128(int256 value) internal pure returns (int128 downcasted) {
downcasted = int128(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(128, value);
}
}
/**
* @dev Returns the downcasted int120 from int256, reverting on
* overflow (when the input is less than smallest int120 or
* greater than largest int120).
*
* Counterpart to Solidity's `int120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*/
function toInt120(int256 value) internal pure returns (int120 downcasted) {
downcasted = int120(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(120, value);
}
}
/**
* @dev Returns the downcasted int112 from int256, reverting on
* overflow (when the input is less than smallest int112 or
* greater than largest int112).
*
* Counterpart to Solidity's `int112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*/
function toInt112(int256 value) internal pure returns (int112 downcasted) {
downcasted = int112(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(112, value);
}
}
/**
* @dev Returns the downcasted int104 from int256, reverting on
* overflow (when the input is less than smallest int104 or
* greater than largest int104).
*
* Counterpart to Solidity's `int104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*/
function toInt104(int256 value) internal pure returns (int104 downcasted) {
downcasted = int104(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(104, value);
}
}
/**
* @dev Returns the downcasted int96 from int256, reverting on
* overflow (when the input is less than smallest int96 or
* greater than largest int96).
*
* Counterpart to Solidity's `int96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*/
function toInt96(int256 value) internal pure returns (int96 downcasted) {
downcasted = int96(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(96, value);
}
}
/**
* @dev Returns the downcasted int88 from int256, reverting on
* overflow (when the input is less than smallest int88 or
* greater than largest int88).
*
* Counterpart to Solidity's `int88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*/
function toInt88(int256 value) internal pure returns (int88 downcasted) {
downcasted = int88(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(88, value);
}
}
/**
* @dev Returns the downcasted int80 from int256, reverting on
* overflow (when the input is less than smallest int80 or
* greater than largest int80).
*
* Counterpart to Solidity's `int80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*/
function toInt80(int256 value) internal pure returns (int80 downcasted) {
downcasted = int80(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(80, value);
}
}
/**
* @dev Returns the downcasted int72 from int256, reverting on
* overflow (when the input is less than smallest int72 or
* greater than largest int72).
*
* Counterpart to Solidity's `int72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*/
function toInt72(int256 value) internal pure returns (int72 downcasted) {
downcasted = int72(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(72, value);
}
}
/**
* @dev Returns the downcasted int64 from int256, reverting on
* overflow (when the input is less than smallest int64 or
* greater than largest int64).
*
* Counterpart to Solidity's `int64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*/
function toInt64(int256 value) internal pure returns (int64 downcasted) {
downcasted = int64(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(64, value);
}
}
/**
* @dev Returns the downcasted int56 from int256, reverting on
* overflow (when the input is less than smallest int56 or
* greater than largest int56).
*
* Counterpart to Solidity's `int56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*/
function toInt56(int256 value) internal pure returns (int56 downcasted) {
downcasted = int56(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(56, value);
}
}
/**
* @dev Returns the downcasted int48 from int256, reverting on
* overflow (when the input is less than smallest int48 or
* greater than largest int48).
*
* Counterpart to Solidity's `int48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*/
function toInt48(int256 value) internal pure returns (int48 downcasted) {
downcasted = int48(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(48, value);
}
}
/**
* @dev Returns the downcasted int40 from int256, reverting on
* overflow (when the input is less than smallest int40 or
* greater than largest int40).
*
* Counterpart to Solidity's `int40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*/
function toInt40(int256 value) internal pure returns (int40 downcasted) {
downcasted = int40(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(40, value);
}
}
/**
* @dev Returns the downcasted int32 from int256, reverting on
* overflow (when the input is less than smallest int32 or
* greater than largest int32).
*
* Counterpart to Solidity's `int32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*/
function toInt32(int256 value) internal pure returns (int32 downcasted) {
downcasted = int32(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(32, value);
}
}
/**
* @dev Returns the downcasted int24 from int256, reverting on
* overflow (when the input is less than smallest int24 or
* greater than largest int24).
*
* Counterpart to Solidity's `int24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*/
function toInt24(int256 value) internal pure returns (int24 downcasted) {
downcasted = int24(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(24, value);
}
}
/**
* @dev Returns the downcasted int16 from int256, reverting on
* overflow (when the input is less than smallest int16 or
* greater than largest int16).
*
* Counterpart to Solidity's `int16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*/
function toInt16(int256 value) internal pure returns (int16 downcasted) {
downcasted = int16(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(16, value);
}
}
/**
* @dev Returns the downcasted int8 from int256, reverting on
* overflow (when the input is less than smallest int8 or
* greater than largest int8).
*
* Counterpart to Solidity's `int8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*/
function toInt8(int256 value) internal pure returns (int8 downcasted) {
downcasted = int8(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(8, value);
}
}
/**
* @dev Converts an unsigned uint256 into a signed int256.
*
* Requirements:
*
* - input must be less than or equal to maxInt256.
*/
function toInt256(uint256 value) internal pure returns (int256) {
// Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
if (value > uint256(type(int256).max)) {
revert SafeCastOverflowedUintToInt(value);
}
return int256(value);
}
/**
* @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump.
*/
function toUint(bool b) internal pure returns (uint256 u) {
assembly ("memory-safe") {
u := iszero(iszero(b))
}
}
}
Ownable.sol 100 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
Context.sol 28 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
Read Contract
assetState 0x74bd94ca → uint96, uint96, uint48
config 0x79502c55 → uint64, uint48, uint48
getAssetHealth 0x95453b99 → uint256, uint256, uint256, uint256, uint256
getAssetState 0xaddeec05 → uint256, uint256, uint256
getConfig 0xc3f909d4 → uint256, uint256, uint256
getProtectedContracts 0x1438291d → address[]
getRawAssetState 0x6ab79e55 → uint256, uint256, uint256
getSystemStatus 0x50c1d19d → bool, address, uint256, uint256, uint256, uint256, uint256
getTrackedAssets 0xc4b97370 → address[]
isActive 0x22f3e2d4 → bool
isTrackedAsset 0x797ed339 → bool
owner 0x8da5cb5b → address
paused 0x5c975abb → bool
pendingOwner 0xe30c3978 → address
protectedContractCount 0xd604b6f3 → uint256
protectedContracts 0x1ec01d71 → bool
trackedAssetCount 0x995be491 → uint256
withdrawalCapacity 0x4eeda9b3 → uint256
Write Contract 11 functions
These functions modify contract state and require a wallet transaction to execute.
acceptOwnership 0x79ba5097
No parameters
addProtectedContract 0x9d9b879f
address protectedContract
checkAndRecordOutflow 0x0f3482f4
address asset
uint256 amount
uint256 preTvl
returns: bool, uint256
emergencyOverride 0x79231b55
address asset
uint256 amount
pause 0x8456cb59
No parameters
recordInflow 0xa69fe863
address asset
uint256 amount
uint256 preTvl
removeProtectedContract 0x7e6561d1
address protectedContract
renounceOwnership 0x715018a6
No parameters
transferOwnership 0xf2fde38b
address newOwner
unpause 0x3f4ba83a
No parameters
updateConfig 0x73ad4946
uint256 maxDrawRateWad
uint256 mainWindow
uint256 elasticWindow
Recent Transactions
This address has 1 on-chain transactions, but only 0.8% of the chain is indexed. Transactions will appear as indexing progresses. View on Etherscan →