编译器
0.8.16+commit.07a7930e
文件 1 的 11:AccessControl.sol
pragma solidity ^0.8.0;
import "contracts/external/openzeppelin/contracts/access/IAccessControl.sol";
import "contracts/external/openzeppelin/contracts/utils/Context.sol";
import "contracts/external/openzeppelin/contracts/utils/Strings.sol";
import "contracts/external/openzeppelin/contracts/utils/ERC165.sol";
abstract contract AccessControl is Context, IAccessControl, ERC165 {
struct RoleData {
mapping(address => bool) members;
bytes32 adminRole;
}
mapping(bytes32 => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
modifier onlyRole(bytes32 role) {
_checkRole(role, _msgSender());
_;
}
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override
returns (bool)
{
return
interfaceId == type(IAccessControl).interfaceId ||
super.supportsInterface(interfaceId);
}
function hasRole(bytes32 role, address account)
public
view
virtual
override
returns (bool)
{
return _roles[role].members[account];
}
function _checkRole(bytes32 role, address account) internal view virtual {
if (!hasRole(role, account)) {
revert(
string(
abi.encodePacked(
"AccessControl: account ",
Strings.toHexString(uint160(account), 20),
" is missing role ",
Strings.toHexString(uint256(role), 32)
)
)
);
}
}
function getRoleAdmin(bytes32 role)
public
view
virtual
override
returns (bytes32)
{
return _roles[role].adminRole;
}
function grantRole(bytes32 role, address account)
public
virtual
override
onlyRole(getRoleAdmin(role))
{
_grantRole(role, account);
}
function revokeRole(bytes32 role, address account)
public
virtual
override
onlyRole(getRoleAdmin(role))
{
_revokeRole(role, account);
}
function renounceRole(bytes32 role, address account) public virtual override {
require(
account == _msgSender(),
"AccessControl: can only renounce roles for self"
);
_revokeRole(role, account);
}
function _setupRole(bytes32 role, address account) internal virtual {
_grantRole(role, account);
}
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
bytes32 previousAdminRole = getRoleAdmin(role);
_roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
function _grantRole(bytes32 role, address account) internal virtual {
if (!hasRole(role, account)) {
_roles[role].members[account] = true;
emit RoleGranted(role, account, _msgSender());
}
}
function _revokeRole(bytes32 role, address account) internal virtual {
if (hasRole(role, account)) {
_roles[role].members[account] = false;
emit RoleRevoked(role, account, _msgSender());
}
}
}
文件 2 的 11:AccessControlEnumerable.sol
pragma solidity ^0.8.0;
import "contracts/external/openzeppelin/contracts/access/IAccessControlEnumerable.sol";
import "contracts/external/openzeppelin/contracts/access/AccessControl.sol";
import "contracts/external/openzeppelin/contracts/utils/EnumerableSet.sol";
abstract contract AccessControlEnumerable is
IAccessControlEnumerable,
AccessControl
{
using EnumerableSet for EnumerableSet.AddressSet;
mapping(bytes32 => EnumerableSet.AddressSet) private _roleMembers;
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override
returns (bool)
{
return
interfaceId == type(IAccessControlEnumerable).interfaceId ||
super.supportsInterface(interfaceId);
}
function getRoleMember(bytes32 role, uint256 index)
public
view
virtual
override
returns (address)
{
return _roleMembers[role].at(index);
}
function getRoleMemberCount(bytes32 role)
public
view
virtual
override
returns (uint256)
{
return _roleMembers[role].length();
}
function _grantRole(bytes32 role, address account) internal virtual override {
super._grantRole(role, account);
_roleMembers[role].add(account);
}
function _revokeRole(bytes32 role, address account)
internal
virtual
override
{
super._revokeRole(role, account);
_roleMembers[role].remove(account);
}
}
文件 3 的 11:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 4 的 11:ERC165.sol
pragma solidity ^0.8.0;
import "contracts/external/openzeppelin/contracts/utils/IERC165.sol";
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override
returns (bool)
{
return interfaceId == type(IERC165).interfaceId;
}
}
文件 5 的 11:EnumerableSet.sol
pragma solidity ^0.8.0;
library EnumerableSet {
struct Set {
bytes32[] _values;
mapping(bytes32 => uint256) _indexes;
}
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
set._indexes[value] = set._values.length;
return true;
} else {
return false;
}
}
function _remove(Set storage set, bytes32 value) private returns (bool) {
uint256 valueIndex = set._indexes[value];
if (valueIndex != 0) {
uint256 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
if (lastIndex != toDeleteIndex) {
bytes32 lastvalue = set._values[lastIndex];
set._values[toDeleteIndex] = lastvalue;
set._indexes[lastvalue] = valueIndex;
}
set._values.pop();
delete set._indexes[value];
return true;
} else {
return false;
}
}
function _contains(Set storage set, bytes32 value)
private
view
returns (bool)
{
return set._indexes[value] != 0;
}
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
function _at(Set storage set, uint256 index) private view returns (bytes32) {
return set._values[index];
}
function _values(Set storage set) private view returns (bytes32[] memory) {
return set._values;
}
struct Bytes32Set {
Set _inner;
}
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
function remove(Bytes32Set storage set, bytes32 value)
internal
returns (bool)
{
return _remove(set._inner, value);
}
function contains(Bytes32Set storage set, bytes32 value)
internal
view
returns (bool)
{
return _contains(set._inner, value);
}
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(Bytes32Set storage set, uint256 index)
internal
view
returns (bytes32)
{
return _at(set._inner, index);
}
function values(Bytes32Set storage set)
internal
view
returns (bytes32[] memory)
{
return _values(set._inner);
}
struct AddressSet {
Set _inner;
}
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
function remove(AddressSet storage set, address value)
internal
returns (bool)
{
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
function contains(AddressSet storage set, address value)
internal
view
returns (bool)
{
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(AddressSet storage set, uint256 index)
internal
view
returns (address)
{
return address(uint160(uint256(_at(set._inner, index))));
}
function values(AddressSet storage set)
internal
view
returns (address[] memory)
{
bytes32[] memory store = _values(set._inner);
address[] memory result;
assembly {
result := store
}
return result;
}
struct UintSet {
Set _inner;
}
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
function contains(UintSet storage set, uint256 value)
internal
view
returns (bool)
{
return _contains(set._inner, bytes32(value));
}
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(UintSet storage set, uint256 index)
internal
view
returns (uint256)
{
return uint256(_at(set._inner, index));
}
function values(UintSet storage set)
internal
view
returns (uint256[] memory)
{
bytes32[] memory store = _values(set._inner);
uint256[] memory result;
assembly {
result := store
}
return result;
}
}
文件 6 的 11:IAccessControl.sol
pragma solidity ^0.8.0;
interface IAccessControl {
event RoleAdminChanged(
bytes32 indexed role,
bytes32 indexed previousAdminRole,
bytes32 indexed newAdminRole
);
event RoleGranted(
bytes32 indexed role,
address indexed account,
address indexed sender
);
event RoleRevoked(
bytes32 indexed role,
address indexed account,
address indexed sender
);
function hasRole(bytes32 role, address account) external view returns (bool);
function getRoleAdmin(bytes32 role) external view returns (bytes32);
function grantRole(bytes32 role, address account) external;
function revokeRole(bytes32 role, address account) external;
function renounceRole(bytes32 role, address account) external;
}
文件 7 的 11:IAccessControlEnumerable.sol
pragma solidity ^0.8.0;
import "contracts/external/openzeppelin/contracts/access/IAccessControl.sol";
interface IAccessControlEnumerable is IAccessControl {
function getRoleMember(bytes32 role, uint256 index)
external
view
returns (address);
function getRoleMemberCount(bytes32 role) external view returns (uint256);
}
文件 8 的 11:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 9 的 11:IInvestorBasedRateLimiter.sol
pragma solidity 0.8.16;
interface IInvestorBasedRateLimiter {
function checkAndUpdateMintLimit(
address investorAddress,
uint256 mintAmount
) external;
function checkAndUpdateRedemptionLimit(
address investorAddress,
uint256 redemptionAmount
) external;
}
文件 10 的 11:InvestorBasedRateLimiter.sol
pragma solidity 0.8.16;
import "contracts/interfaces/IInvestorBasedRateLimiter.sol";
import "contracts/external/openzeppelin/contracts/access/AccessControlEnumerable.sol";
contract InvestorBasedRateLimiter is
IInvestorBasedRateLimiter,
AccessControlEnumerable
{
bytes32 public constant CLIENT_ROLE = keccak256("CLIENT_ROLE");
bytes32 public constant CONFIGURER_ROLE = keccak256("CONFIGURER_ROLE");
struct RateLimit {
uint256 currentAmount;
uint256 limit;
uint256 lastResetTime;
uint256 limitDuration;
}
mapping(uint256 => RateLimit) public investorIdToMintState;
mapping(uint256 => RateLimit) public investorIdToRedemptionState;
mapping(address => uint256) public addressToInvestorId;
mapping(uint256 => uint256) public investorAddressCount;
uint256 public defaultMintLimit = 5_000_000 * 1e6;
uint256 public defaultRedemptionLimit = 5_000_000 * 1e6;
uint256 public defaultMintLimitDuration = 1 days;
uint256 public defaultRedemptionLimitDuration = 1 days;
uint256 public investorIdCounter;
constructor(address admin, address client) {
_setupRole(DEFAULT_ADMIN_ROLE, admin);
_setupRole(CONFIGURER_ROLE, admin);
_setupRole(CLIENT_ROLE, client);
}
function checkAndUpdateMintLimit(
address investorAddress,
uint256 mintAmount
) external override onlyRole(CLIENT_ROLE) {
if (mintAmount == 0) {
revert InvalidAmount();
}
uint256 investorId = addressToInvestorId[investorAddress];
if (investorId == 0) {
address[] memory addresses = new address[](1);
addresses[0] = investorAddress;
investorId = _initializeInvestorState(
addresses,
defaultMintLimit,
defaultRedemptionLimit,
defaultMintLimitDuration,
defaultRedemptionLimitDuration
);
}
RateLimit storage mintState = investorIdToMintState[investorId];
uint256 prevAmount = mintState.currentAmount;
_checkAndUpdateRateLimitState(mintState, mintAmount);
emit MintStateUpdated(
investorAddress,
investorId,
prevAmount,
mintState.currentAmount,
mintState.limit - mintState.currentAmount
);
}
function checkAndUpdateRedemptionLimit(
address investorAddress,
uint256 redemptionAmount
) external override onlyRole(CLIENT_ROLE) {
if (redemptionAmount == 0) {
revert InvalidAmount();
}
uint256 investorId = addressToInvestorId[investorAddress];
if (investorId == 0) {
address[] memory addresses = new address[](1);
addresses[0] = investorAddress;
investorId = _initializeInvestorState(
addresses,
defaultMintLimit,
defaultRedemptionLimit,
defaultMintLimitDuration,
defaultRedemptionLimitDuration
);
}
RateLimit storage redemptionState = investorIdToRedemptionState[investorId];
uint256 prevAmount = redemptionState.currentAmount;
_checkAndUpdateRateLimitState(redemptionState, redemptionAmount);
emit RedemptionStateUpdated(
investorAddress,
investorId,
prevAmount,
redemptionState.currentAmount,
redemptionState.limit - redemptionState.currentAmount
);
}
function _checkAndUpdateRateLimitState(
RateLimit storage rateLimit,
uint256 amount
) internal {
if (block.timestamp >= rateLimit.lastResetTime + rateLimit.limitDuration) {
rateLimit.currentAmount = 0;
rateLimit.lastResetTime = block.timestamp;
}
if (rateLimit.currentAmount + amount > rateLimit.limit) {
revert RateLimitExceeded();
}
rateLimit.currentAmount += amount;
}
function initializeInvestorStateDefault(
address[] memory addresses
) external onlyRole(CONFIGURER_ROLE) {
_initializeInvestorState(
addresses,
defaultMintLimit,
defaultRedemptionLimit,
defaultMintLimitDuration,
defaultRedemptionLimitDuration
);
}
function _initializeInvestorState(
address[] memory addresses,
uint256 mintLimit,
uint256 redemptionLimit,
uint256 mintLimitDuration,
uint256 redemptionLimitDuration
) internal returns (uint256 investorId) {
if (addresses.length == 0) revert AddressesNotProvided();
investorId = ++investorIdCounter;
for (uint256 i; i < addresses.length; ++i) {
if (addressToInvestorId[addresses[i]] != 0) {
revert AddressAlreadyAssociated();
}
_setAddressToInvestorId(addresses[i], investorId);
}
investorIdToMintState[investorId] = RateLimit({
currentAmount: 0,
limit: mintLimit,
lastResetTime: block.timestamp,
limitDuration: mintLimitDuration
});
investorIdToRedemptionState[investorId] = RateLimit({
currentAmount: 0,
limit: redemptionLimit,
lastResetTime: block.timestamp,
limitDuration: redemptionLimitDuration
});
}
function setAddressToInvestorId(
address investorAddress,
uint256 newInvestorId
) external onlyRole(CONFIGURER_ROLE) {
if (newInvestorId == 0) {
revert InvalidInvestorId();
}
if (investorIdToMintState[newInvestorId].lastResetTime == 0) {
revert InvestorNotFound();
}
_setAddressToInvestorId(investorAddress, newInvestorId);
}
function removeAddress(
address investorAddress
) external onlyRole(CONFIGURER_ROLE) {
_setAddressToInvestorId(investorAddress, 0);
}
function _setAddressToInvestorId(
address investorAddress,
uint256 newInvestorId
) internal {
if (investorAddress == address(0)) revert AddressCannotBeZero();
if (addressToInvestorId[investorAddress] == newInvestorId) {
revert AddressAlreadyAssociated();
}
uint256 previousInvestorId = addressToInvestorId[investorAddress];
if (previousInvestorId != 0) {
--investorAddressCount[previousInvestorId];
emit AddressRemovedFromInvestorId(
investorAddress,
previousInvestorId,
investorAddressCount[previousInvestorId]
);
}
if (newInvestorId != 0) {
++investorAddressCount[newInvestorId];
emit AddressToInvestorIdSet(
investorAddress,
newInvestorId,
investorAddressCount[newInvestorId]
);
}
addressToInvestorId[investorAddress] = newInvestorId;
}
function setInvestorMintLimit(
uint256 investorId,
uint256 mintLimit
) external onlyRole(CONFIGURER_ROLE) {
RateLimit storage mintState = investorIdToMintState[investorId];
if (mintState.lastResetTime == 0) {
revert InvestorNotFound();
}
emit MintLimitSet(investorId, mintState.limit, mintLimit);
mintState.limit = mintLimit;
}
function setInvestorRedemptionLimit(
uint256 investorId,
uint256 redemptionLimit
) external onlyRole(CONFIGURER_ROLE) {
RateLimit storage redemptionState = investorIdToRedemptionState[investorId];
if (redemptionState.lastResetTime == 0) {
revert InvestorNotFound();
}
emit RedemptionLimitSet(investorId, redemptionState.limit, redemptionLimit);
redemptionState.limit = redemptionLimit;
}
function setInvestorMintLimitDuration(
uint256 investorId,
uint256 mintLimitDuration
) external onlyRole(CONFIGURER_ROLE) {
RateLimit storage mintState = investorIdToMintState[investorId];
if (mintState.lastResetTime == 0) {
revert InvestorNotFound();
}
emit MintLimitDurationSet(
investorId,
mintState.limitDuration,
mintLimitDuration
);
mintState.limitDuration = mintLimitDuration;
}
function setInvestorRedemptionLimitDuration(
uint256 investorId,
uint256 redemptionLimitDuration
) external onlyRole(CONFIGURER_ROLE) {
RateLimit storage redemptionState = investorIdToRedemptionState[investorId];
if (redemptionState.lastResetTime == 0) {
revert InvestorNotFound();
}
emit RedemptionLimitDurationSet(
investorId,
redemptionState.limitDuration,
redemptionLimitDuration
);
redemptionState.limitDuration = redemptionLimitDuration;
}
function resetInvestorMintState(
uint256 investorId,
uint256 prevLastMintResetTime,
uint256 prevMintAmount
) external onlyRole(CONFIGURER_ROLE) {
RateLimit storage mintState = investorIdToMintState[investorId];
if (mintState.lastResetTime == 0) {
revert InvestorNotFound();
}
if (mintState.currentAmount != prevMintAmount) {
revert CurrentAmountMismatch();
}
if (mintState.lastResetTime != prevLastMintResetTime) {
revert InvalidResetTime();
}
mintState.lastResetTime = block.timestamp;
mintState.currentAmount = 0;
emit MintStateReset(investorId, prevLastMintResetTime, block.timestamp);
}
function resetInvestorRedemptionState(
uint256 investorId,
uint256 prevLastRedemptionResetTime,
uint256 prevRedemptionAmount
) external onlyRole(CONFIGURER_ROLE) {
RateLimit storage redemptionState = investorIdToRedemptionState[investorId];
if (redemptionState.lastResetTime == 0) {
revert InvestorNotFound();
}
if (redemptionState.currentAmount != prevRedemptionAmount) {
revert CurrentAmountMismatch();
}
if (redemptionState.lastResetTime != prevLastRedemptionResetTime) {
revert InvalidResetTime();
}
redemptionState.lastResetTime = block.timestamp;
redemptionState.currentAmount = 0;
emit RedemptionStateReset(
investorId,
prevLastRedemptionResetTime,
block.timestamp
);
}
function setDefaultMintLimit(
uint256 _defaultMintLimit
) external onlyRole(DEFAULT_ADMIN_ROLE) {
emit DefaultMintLimitSet(defaultMintLimit, _defaultMintLimit);
defaultMintLimit = _defaultMintLimit;
}
function setDefaultRedemptionLimit(
uint256 _defaultRedemptionLimit
) external onlyRole(DEFAULT_ADMIN_ROLE) {
emit DefaultRedemptionLimitSet(
defaultRedemptionLimit,
_defaultRedemptionLimit
);
defaultRedemptionLimit = _defaultRedemptionLimit;
}
function setDefaultMintLimitDuration(
uint256 _defaultMintLimitDuration
) external onlyRole(DEFAULT_ADMIN_ROLE) {
emit DefaultMintLimitDurationSet(
defaultMintLimitDuration,
_defaultMintLimitDuration
);
defaultMintLimitDuration = _defaultMintLimitDuration;
}
function setDefaultRedemptionLimitDuration(
uint256 _defaultRedemptionLimitDuration
) external onlyRole(DEFAULT_ADMIN_ROLE) {
emit DefaultRedemptionLimitDurationSet(
defaultRedemptionLimitDuration,
_defaultRedemptionLimitDuration
);
defaultRedemptionLimitDuration = _defaultRedemptionLimitDuration;
}
event MintStateUpdated(
address indexed investorAddress,
uint256 indexed investorId,
uint256 prevAmount,
uint256 currentAmount,
uint256 remainingAmount
);
event RedemptionStateUpdated(
address indexed investorAddress,
uint256 indexed investorId,
uint256 prevAmount,
uint256 currentAmount,
uint256 remainingAmount
);
event AddressToInvestorIdSet(
address indexed investorAddress,
uint256 indexed investorId,
uint256 indexed investorWallets
);
event AddressRemovedFromInvestorId(
address indexed investorAddress,
uint256 indexed investorId,
uint256 indexed investorWallets
);
event MintLimitSet(
uint256 indexed investorId,
uint256 oldLimit,
uint256 newLimit
);
event RedemptionLimitSet(
uint256 indexed investorId,
uint256 oldLimit,
uint256 newLimit
);
event MintLimitDurationSet(
uint256 indexed investorId,
uint256 oldDuration,
uint256 newDuration
);
event RedemptionLimitDurationSet(
uint256 indexed investorId,
uint256 oldDuration,
uint256 newDuration
);
event MintStateReset(
uint256 indexed investorId,
uint256 oldTime,
uint256 newTime
);
event RedemptionStateReset(
uint256 indexed investorId,
uint256 oldTime,
uint256 newTime
);
event DefaultMintLimitSet(uint256 oldLimit, uint256 newLimit);
event DefaultRedemptionLimitSet(uint256 oldLimit, uint256 newLimit);
event DefaultMintLimitDurationSet(uint256 oldDuration, uint256 newDuration);
event DefaultRedemptionLimitDurationSet(
uint256 oldDuration,
uint256 newDuration
);
error AddressAlreadyAssociated();
error AddressCannotBeZero();
error AddressesNotProvided();
error InvestorNotIntialized();
error InvestorAlreadyInitialized();
error InvestorNotFound();
error InvalidInvestorId();
error InvalidResetTime();
error CurrentAmountMismatch();
error InvalidAmount();
error RateLimitExceeded();
}
文件 11 的 11:Strings.sol
pragma solidity ^0.8.0;
library Strings {
bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
function toString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
function toHexString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0x00";
}
uint256 temp = value;
uint256 length = 0;
while (temp != 0) {
length++;
temp >>= 8;
}
return toHexString(value, length);
}
function toHexString(uint256 value, uint256 length)
internal
pure
returns (string memory)
{
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _HEX_SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
}
{
"compilationTarget": {
"contracts/ousg/InvestorBasedRateLimiter.sol": "InvestorBasedRateLimiter"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 100
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"admin","type":"address"},{"internalType":"address","name":"client","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AddressAlreadyAssociated","type":"error"},{"inputs":[],"name":"AddressCannotBeZero","type":"error"},{"inputs":[],"name":"AddressesNotProvided","type":"error"},{"inputs":[],"name":"CurrentAmountMismatch","type":"error"},{"inputs":[],"name":"InvalidAmount","type":"error"},{"inputs":[],"name":"InvalidInvestorId","type":"error"},{"inputs":[],"name":"InvalidResetTime","type":"error"},{"inputs":[],"name":"InvestorAlreadyInitialized","type":"error"},{"inputs":[],"name":"InvestorNotFound","type":"error"},{"inputs":[],"name":"InvestorNotIntialized","type":"error"},{"inputs":[],"name":"RateLimitExceeded","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"investorAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"investorId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"investorWallets","type":"uint256"}],"name":"AddressRemovedFromInvestorId","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"investorAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"investorId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"investorWallets","type":"uint256"}],"name":"AddressToInvestorIdSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldDuration","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newDuration","type":"uint256"}],"name":"DefaultMintLimitDurationSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldLimit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newLimit","type":"uint256"}],"name":"DefaultMintLimitSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldDuration","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newDuration","type":"uint256"}],"name":"DefaultRedemptionLimitDurationSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldLimit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newLimit","type":"uint256"}],"name":"DefaultRedemptionLimitSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"investorId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"oldDuration","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newDuration","type":"uint256"}],"name":"MintLimitDurationSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"investorId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"oldLimit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newLimit","type":"uint256"}],"name":"MintLimitSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"investorId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"oldTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newTime","type":"uint256"}],"name":"MintStateReset","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"investorAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"investorId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"prevAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"currentAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"remainingAmount","type":"uint256"}],"name":"MintStateUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"investorId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"oldDuration","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newDuration","type":"uint256"}],"name":"RedemptionLimitDurationSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"investorId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"oldLimit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newLimit","type":"uint256"}],"name":"RedemptionLimitSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"investorId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"oldTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newTime","type":"uint256"}],"name":"RedemptionStateReset","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"investorAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"investorId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"prevAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"currentAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"remainingAmount","type":"uint256"}],"name":"RedemptionStateUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"inputs":[],"name":"CLIENT_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CONFIGURER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"addressToInvestorId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"investorAddress","type":"address"},{"internalType":"uint256","name":"mintAmount","type":"uint256"}],"name":"checkAndUpdateMintLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"investorAddress","type":"address"},{"internalType":"uint256","name":"redemptionAmount","type":"uint256"}],"name":"checkAndUpdateRedemptionLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"defaultMintLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultMintLimitDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultRedemptionLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultRedemptionLimitDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"addresses","type":"address[]"}],"name":"initializeInvestorStateDefault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"investorAddressCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"investorIdCounter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"investorIdToMintState","outputs":[{"internalType":"uint256","name":"currentAmount","type":"uint256"},{"internalType":"uint256","name":"limit","type":"uint256"},{"internalType":"uint256","name":"lastResetTime","type":"uint256"},{"internalType":"uint256","name":"limitDuration","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"investorIdToRedemptionState","outputs":[{"internalType":"uint256","name":"currentAmount","type":"uint256"},{"internalType":"uint256","name":"limit","type":"uint256"},{"internalType":"uint256","name":"lastResetTime","type":"uint256"},{"internalType":"uint256","name":"limitDuration","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"investorAddress","type":"address"}],"name":"removeAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"investorId","type":"uint256"},{"internalType":"uint256","name":"prevLastMintResetTime","type":"uint256"},{"internalType":"uint256","name":"prevMintAmount","type":"uint256"}],"name":"resetInvestorMintState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"investorId","type":"uint256"},{"internalType":"uint256","name":"prevLastRedemptionResetTime","type":"uint256"},{"internalType":"uint256","name":"prevRedemptionAmount","type":"uint256"}],"name":"resetInvestorRedemptionState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"investorAddress","type":"address"},{"internalType":"uint256","name":"newInvestorId","type":"uint256"}],"name":"setAddressToInvestorId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_defaultMintLimit","type":"uint256"}],"name":"setDefaultMintLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_defaultMintLimitDuration","type":"uint256"}],"name":"setDefaultMintLimitDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_defaultRedemptionLimit","type":"uint256"}],"name":"setDefaultRedemptionLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_defaultRedemptionLimitDuration","type":"uint256"}],"name":"setDefaultRedemptionLimitDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"investorId","type":"uint256"},{"internalType":"uint256","name":"mintLimit","type":"uint256"}],"name":"setInvestorMintLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"investorId","type":"uint256"},{"internalType":"uint256","name":"mintLimitDuration","type":"uint256"}],"name":"setInvestorMintLimitDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"investorId","type":"uint256"},{"internalType":"uint256","name":"redemptionLimit","type":"uint256"}],"name":"setInvestorRedemptionLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"investorId","type":"uint256"},{"internalType":"uint256","name":"redemptionLimitDuration","type":"uint256"}],"name":"setInvestorRedemptionLimitDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]