Contract detail
RateLimits
RateLimits is a verified Robinhood Chain smart contract at 0x5c1fde9d…232c68a0 with 7 indexed transactions.
- Address type
- Smart contract
- Transactions
- 7
- First indexed block
- #31318
- Latest indexed block
- #72469443
- ERC-20 transfers
- 1
- Emitted events
- 8
- Verification
- Verified
- Compiler
- v0.8.25+commit.b61c2a91
- Verification match
- full
- Creation transaction
- 0xfcbc4431…e1c5efde
- Created at block
- #31318
- Language
- solidity
- EVM version
- cancun
- License
- gnu_agpl_v3
- Compiler optimization
- Enabled · 1 runs
Related activity
Transactions
Verified contract
Contract source code
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.21;
import { AccessControl } from "openzeppelin-contracts/contracts/access/AccessControl.sol";
import { IRateLimits } from "./interfaces/IRateLimits.sol";
contract RateLimits is IRateLimits, AccessControl {
/**********************************************************************************************/
/*** State variables ***/
/**********************************************************************************************/
bytes32 public override constant CONTROLLER = keccak256("CONTROLLER");
mapping(bytes32 => RateLimitData) private _data;
/**********************************************************************************************/
/*** Initialization ***/
/**********************************************************************************************/
constructor(address admin_) {
_grantRole(DEFAULT_ADMIN_ROLE, admin_);
}
/**********************************************************************************************/
/*** Admin functions ***/
/**********************************************************************************************/
function setRateLimitData(
bytes32 key,
uint256 maxAmount,
uint256 slope,
uint256 lastAmount,
uint256 lastUpdated
)
public override onlyRole(DEFAULT_ADMIN_ROLE)
{
require(lastAmount <= maxAmount, "RateLimits/invalid-lastAmount");
require(lastUpdated <= block.timestamp, "RateLimits/invalid-lastUpdated");
_data[key] = RateLimitData({
maxAmount: maxAmount,
slope: slope,
lastAmount: lastAmount,
lastUpdated: lastUpdated
});
emit RateLimitDataSet(key, maxAmount, slope, lastAmount, lastUpdated);
}
function setRateLimitData(bytes32 key, uint256 maxAmount, uint256 slope) external override {
setRateLimitData(key, maxAmount, slope, maxAmount, block.timestamp);
}
function setUnlimitedRateLimitData(bytes32 key) external override {
setRateLimitData(key, type(uint256).max, 0, type(uint256).max, block.timestamp);
}
/**********************************************************************************************/
/*** Getter Functions ***/
/**********************************************************************************************/
function getRateLimitData(bytes32 key) external override view returns (RateLimitData memory) {
return _data[key];
}
function getCurrentRateLimit(bytes32 key) public override view returns (uint256) {
RateLimitData memory d = _data[key];
// Unlimited rate limit case
if (d.maxAmount == type(uint256).max) {
return type(uint256).max;
}
return _min(
d.slope * (block.timestamp - d.lastUpdated) + d.lastAmount,
d.maxAmount
);
}
/**********************************************************************************************/
/*** Controller functions ***/
/**********************************************************************************************/
function triggerRateLimitDecrease(bytes32 key, uint256 amountToDecrease)
external
override
onlyRole(CONTROLLER)
returns (uint256 newLimit)
{
RateLimitData storage d = _data[key];
uint256 maxAmount = d.maxAmount;
require(maxAmount > 0, "RateLimits/zero-maxAmount");
if (maxAmount == type(uint256).max) return type(uint256).max; // Special case unlimited
uint256 currentRateLimit = getCurrentRateLimit(key);
require(amountToDecrease <= currentRateLimit, "RateLimits/rate-limit-exceeded");
d.lastAmount = newLimit = currentRateLimit - amountToDecrease;
d.lastUpdated = block.timestamp;
emit RateLimitDecreaseTriggered(key, amountToDecrease, currentRateLimit, newLimit);
}
function triggerRateLimitIncrease(bytes32 key, uint256 amountToIncrease)
external
override
onlyRole(CONTROLLER)
returns (uint256 newLimit)
{
RateLimitData storage d = _data[key];
uint256 maxAmount = d.maxAmount;
require(maxAmount > 0, "RateLimits/zero-maxAmount");
if (maxAmount == type(uint256).max) return type(uint256).max; // Special case unlimited
uint256 currentRateLimit = getCurrentRateLimit(key);
d.lastAmount = newLimit = _min(currentRateLimit + amountToIncrease, maxAmount);
d.lastUpdated = block.timestamp;
emit RateLimitIncreaseTriggered(key, amountToIncrease, currentRateLimit, newLimit);
}
/**********************************************************************************************/
/*** Internal Utility Functions ***/
/**********************************************************************************************/
function _min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
}