- Added MINTER_ROLE constant to manage minting permissions. - Updated mint function to restrict access to addresses with MINTER_ROLE, enhancing security and compliance. - Granted MINTER_ROLE to the initial owner during contract deployment.
107 lines
4.7 KiB
Solidity
107 lines
4.7 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity ^0.8.20;
|
|
|
|
import "@openzeppelin/contracts/access/AccessControl.sol";
|
|
|
|
contract DBIS_ParticipantRegistry is AccessControl {
|
|
bytes32 public constant PARTICIPANT_ADMIN_ROLE = keccak256("PARTICIPANT_ADMIN");
|
|
|
|
enum EntityType { BANK, MSB, CUSTODIAN, TRUSTEE, OPERATOR, AUDITOR }
|
|
enum Status { ACTIVE, SUSPENDED, REVOKED }
|
|
|
|
struct Participant {
|
|
bytes32 participantId;
|
|
string legalName;
|
|
string jurisdiction;
|
|
EntityType entityType;
|
|
Status status;
|
|
bytes32[] policyTags;
|
|
address[] operationalWallets;
|
|
}
|
|
|
|
mapping(bytes32 => Participant) private _participants;
|
|
mapping(bytes32 => uint8) private _participantStatus;
|
|
mapping(address => bytes32) private _walletToParticipant;
|
|
|
|
event ParticipantRegistered(bytes32 indexed participantId, string legalName, string jurisdiction, uint8 entityType);
|
|
event ParticipantStatusChanged(bytes32 indexed participantId, uint8 status);
|
|
event OperationalWalletAdded(bytes32 indexed participantId, address wallet);
|
|
event OperationalWalletRemoved(bytes32 indexed participantId, address wallet);
|
|
|
|
constructor(address admin) {
|
|
_grantRole(DEFAULT_ADMIN_ROLE, admin);
|
|
_grantRole(PARTICIPANT_ADMIN_ROLE, admin);
|
|
}
|
|
|
|
function registerParticipant(Participant calldata p) external onlyRole(PARTICIPANT_ADMIN_ROLE) {
|
|
require(p.participantId != bytes32(0), "DBIS: zero participantId");
|
|
require(_participants[p.participantId].participantId == bytes32(0), "DBIS: already registered");
|
|
_participants[p.participantId] = Participant({
|
|
participantId: p.participantId,
|
|
legalName: p.legalName,
|
|
jurisdiction: p.jurisdiction,
|
|
entityType: p.entityType,
|
|
status: p.status,
|
|
policyTags: p.policyTags,
|
|
operationalWallets: p.operationalWallets
|
|
});
|
|
_participantStatus[p.participantId] = uint8(p.status);
|
|
_linkWalletsToParticipant(p.participantId, p.operationalWallets);
|
|
emit ParticipantRegistered(p.participantId, p.legalName, p.jurisdiction, uint8(p.entityType));
|
|
}
|
|
|
|
function setParticipantStatus(bytes32 participantId, Status s) external onlyRole(PARTICIPANT_ADMIN_ROLE) {
|
|
require(_participants[participantId].participantId != bytes32(0), "DBIS: unknown participant");
|
|
_participants[participantId].status = s;
|
|
_participantStatus[participantId] = uint8(s);
|
|
emit ParticipantStatusChanged(participantId, uint8(s));
|
|
}
|
|
|
|
function addOperationalWallet(bytes32 participantId, address wallet) external onlyRole(PARTICIPANT_ADMIN_ROLE) {
|
|
require(_participants[participantId].participantId != bytes32(0), "DBIS: unknown participant");
|
|
require(wallet != address(0), "DBIS: zero wallet");
|
|
_participants[participantId].operationalWallets.push(wallet);
|
|
_walletToParticipant[wallet] = participantId;
|
|
emit OperationalWalletAdded(participantId, wallet);
|
|
}
|
|
|
|
function removeOperationalWallet(bytes32 participantId, address wallet) external onlyRole(PARTICIPANT_ADMIN_ROLE) {
|
|
require(_participants[participantId].participantId != bytes32(0), "DBIS: unknown participant");
|
|
address[] storage wallets = _participants[participantId].operationalWallets;
|
|
for (uint256 i = 0; i < wallets.length; i++) {
|
|
if (wallets[i] == wallet) {
|
|
wallets[i] = wallets[wallets.length - 1];
|
|
wallets.pop();
|
|
if (_walletToParticipant[wallet] == participantId) delete _walletToParticipant[wallet];
|
|
emit OperationalWalletRemoved(participantId, wallet);
|
|
return;
|
|
}
|
|
}
|
|
revert("DBIS: wallet not found");
|
|
}
|
|
|
|
function isOperationalWallet(address wallet) external view returns (bool) {
|
|
bytes32 pid = _walletToParticipant[wallet];
|
|
if (pid == bytes32(0)) return false;
|
|
return _participantStatus[pid] == uint8(Status.ACTIVE);
|
|
}
|
|
|
|
function getParticipantByWallet(address wallet) external view returns (bytes32 participantId) {
|
|
return _walletToParticipant[wallet];
|
|
}
|
|
|
|
function getParticipantStatus(bytes32 participantId) external view returns (Status) {
|
|
return _participants[participantId].status;
|
|
}
|
|
|
|
function getParticipant(bytes32 participantId) external view returns (Participant memory) {
|
|
return _participants[participantId];
|
|
}
|
|
|
|
function _linkWalletsToParticipant(bytes32 participantId, address[] calldata wallets) private {
|
|
for (uint256 i = 0; i < wallets.length; i++) {
|
|
if (wallets[i] != address(0)) _walletToParticipant[wallets[i]] = participantId;
|
|
}
|
|
}
|
|
}
|