Skip to content

Commit

Permalink
introduce admin (#4)
Browse files Browse the repository at this point in the history
* introduce admin to constructor

* fix tests
  • Loading branch information
seunlanlege authored Oct 9, 2023
1 parent 01a46a2 commit b41cbbe
Show file tree
Hide file tree
Showing 12 changed files with 116 additions and 106 deletions.
42 changes: 18 additions & 24 deletions src/CalculateSelector.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,37 @@ pragma solidity ^0.8.17;
import {IERC6160Ext20} from "./interfaces/IERC6160Ext20.sol";
import {IERC6160Ext721} from "./interfaces/IERC6160Ext721.sol";
import {IERC6160Ext1155} from "./interfaces/IERC6160Ext1155.sol";

contract Calculate {
IERC6160Ext20 ierc6160ext20;
IERC6160Ext721 ierc6160ext721;
IERC6160Ext1155 ierc6160ext1155;

// calculate selector for IERC6160Ext20
function calculateSelectorIERC6160Ext20() external view returns(bytes4) {
bytes4 selector =
(ierc6160ext20.hasRole.selector ^
ierc6160ext20.grantRole.selector ^
ierc6160ext20.revokeRole.selector ^
ierc6160ext20.mint.selector ^
ierc6160ext20.burn.selector);
function calculateSelectorIERC6160Ext20() external view returns (bytes4) {
bytes4 selector = (
ierc6160ext20.hasRole.selector ^ ierc6160ext20.grantRole.selector ^ ierc6160ext20.revokeRole.selector
^ ierc6160ext20.mint.selector ^ ierc6160ext20.burn.selector
);
return selector;
}

// calculate selector for IERC6160Ext721
function calculateSelectorIERC6160Ext721() external view returns(bytes4) {
bytes4 selector =
(ierc6160ext721.hasRole.selector ^
ierc6160ext721.grantRole.selector ^
ierc6160ext721.revokeRole.selector ^
ierc6160ext721.safeMint.selector ^
ierc6160ext721.burn.selector);
function calculateSelectorIERC6160Ext721() external view returns (bytes4) {
bytes4 selector = (
ierc6160ext721.hasRole.selector ^ ierc6160ext721.grantRole.selector ^ ierc6160ext721.revokeRole.selector
^ ierc6160ext721.safeMint.selector ^ ierc6160ext721.burn.selector
);
return selector;
}

// calculate selector for IERC6160Ext1155
function calculateSelectorIERC6160Ext1155() external view returns(bytes4) {
bytes4 selector =
(ierc6160ext1155.hasRole.selector ^
ierc6160ext1155.grantRole.selector ^
ierc6160ext1155.revokeRole.selector ^
ierc6160ext1155.safeMint.selector ^
ierc6160ext1155.safeMintBatch.selector ^
ierc6160ext1155.burn.selector ^
ierc6160ext1155.burnBatch.selector);
function calculateSelectorIERC6160Ext1155() external view returns (bytes4) {
bytes4 selector = (
ierc6160ext1155.hasRole.selector ^ ierc6160ext1155.grantRole.selector ^ ierc6160ext1155.revokeRole.selector
^ ierc6160ext1155.safeMint.selector ^ ierc6160ext1155.safeMintBatch.selector ^ ierc6160ext1155.burn.selector
^ ierc6160ext1155.burnBatch.selector
);
return selector;
}
}
}
13 changes: 7 additions & 6 deletions src/interfaces/IERC6160Ext1155.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import {IERC_ACL_CORE} from "./IERCAclCore.sol";

// The EIP-165 identifier of this interface is 0xf4cedd5a
interface IERC5679Ext1155 {
function safeMint(address _to, uint256 _id, uint256 _amount, bytes calldata _data) external;
function safeMintBatch(address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;
function burn(address _from, uint256 _id, uint256 _amount, bytes[] calldata _data) external;
function burnBatch(address _from, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata _data) external;
function safeMint(address _to, uint256 _id, uint256 _amount, bytes calldata _data) external;
function safeMintBatch(address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data)
external;
function burn(address _from, uint256 _id, uint256 _amount, bytes[] calldata _data) external;
function burnBatch(address _from, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata _data)
external;
}


/**
* @dev Interface of the ERC6160 standard, as defined in
* https://github.com/polytope-labs/EIPs/blob/master/EIPS/eip-6160.md.
Expand All @@ -19,4 +20,4 @@ interface IERC5679Ext1155 {
*
* The EIP-165 identifier of this interface is 0x9f77104c
*/
interface IERC6160Ext1155 is IERC5679Ext1155, IERC_ACL_CORE {}
interface IERC6160Ext1155 is IERC5679Ext1155, IERC_ACL_CORE {}
6 changes: 3 additions & 3 deletions src/interfaces/IERC6160Ext20.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import {IERC_ACL_CORE} from "./IERCAclCore.sol";

// The EIP-165 identifier of this interface is 0xd0017968
interface IERC5679Ext20 {
function mint(address _to, uint256 _amount, bytes calldata _data) external;
function burn(address _from, uint256 _amount, bytes calldata _data) external;
function mint(address _to, uint256 _amount, bytes calldata _data) external;
function burn(address _from, uint256 _amount, bytes calldata _data) external;
}

/**
Expand All @@ -16,4 +16,4 @@ interface IERC5679Ext20 {
*
* The EIP-165 identifier of this interface is 0xbbb8b47e
*/
interface IERC6160Ext20 is IERC5679Ext20, IERC_ACL_CORE {}
interface IERC6160Ext20 is IERC5679Ext20, IERC_ACL_CORE {}
6 changes: 3 additions & 3 deletions src/interfaces/IERC6160Ext721.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import {IERC_ACL_CORE} from "./IERCAclCore.sol";

// The EIP-165 identifier of this interface is 0xcce39764
interface IERC5679Ext721 {
function safeMint(address _to, uint256 _id, bytes calldata _data) external;
function burn(address _from, uint256 _id, bytes calldata _data) external;
function safeMint(address _to, uint256 _id, bytes calldata _data) external;
function burn(address _from, uint256 _id, bytes calldata _data) external;
}

/**
Expand All @@ -16,4 +16,4 @@ interface IERC5679Ext721 {
*
* The EIP-165 identifier of this interface is 0xa75a5a72
*/
interface IERC6160Ext721 is IERC5679Ext721, IERC_ACL_CORE {}
interface IERC6160Ext721 is IERC5679Ext721, IERC_ACL_CORE {}
1 change: 0 additions & 1 deletion src/interfaces/IERCAclCore.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
pragma solidity ^0.8.17;


/**
* @dev Interface of the EIP5982 standard, as defined in
* https://github.com/polytope-labs/EIPs/blob/master/EIPS/eip-5982.md
Expand Down
59 changes: 34 additions & 25 deletions src/tokens/ERC1155.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,46 +27,47 @@ contract MultiChainNativeERC1155 is ERC1155, ERC165Storage, IERC6160Ext1155 {
/// @notice mapping of admins of defined roles
mapping(bytes32 => mapping(address => bool)) _rolesAdmin;

constructor() ERC1155("") {
constructor(address admin, string memory uri) ERC1155(uri) {
_registerInterface(_IERC6160Ext1155_ID_);
_registerInterface(type(IERC5679Ext1155).interfaceId);
_registerInterface(type(IERC_ACL_CORE).interfaceId);

_rolesAdmin[MINTER_ROLE][msg.sender] = true;
_roles[MINTER_ROLE][msg.sender] = true;
_rolesAdmin[MINTER_ROLE][admin] = true;
_roles[MINTER_ROLE][admin] = true;

_rolesAdmin[BURNER_ROLE][msg.sender] = true;
_roles[BURNER_ROLE][msg.sender] = true;
_rolesAdmin[BURNER_ROLE][admin] = true;
_roles[BURNER_ROLE][admin] = true;
}

/// @notice Mints token to the specified account `_to`
function safeMint(address _to, uint256 _id, uint256 _amount, bytes calldata _data) external {
if(!isRoleAdmin(MINTER_ROLE) && !hasRole(MINTER_ROLE, _msgSender())) revert PermissionDenied();
if (!isRoleAdmin(MINTER_ROLE) && !hasRole(MINTER_ROLE, _msgSender())) revert PermissionDenied();
super._mint(_to, _id, _amount, _data);
}

/// @notice Mints token in batch to the specified account `_to`
function safeMintBatch(address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external {
if(!isRoleAdmin(MINTER_ROLE) && !hasRole(MINTER_ROLE, _msgSender())) revert PermissionDenied();
function safeMintBatch(address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data)
external
{
if (!isRoleAdmin(MINTER_ROLE) && !hasRole(MINTER_ROLE, _msgSender())) revert PermissionDenied();
super._mintBatch(to, ids, amounts, data);
}
}

/// @notice Burns token associated with the specified account `_from`
function burn(address _from, uint256 _id, uint256 _amount, bytes[] calldata) external {
function burn(address _from, uint256 _id, uint256 _amount, bytes[] calldata) external {
bool isApproved = isApprovedForAll(_msgSender(), _from);
bool hasBurnRole = isRoleAdmin(BURNER_ROLE) || hasRole(BURNER_ROLE, _msgSender());
if(!isApproved && !hasBurnRole) revert PermissionDenied();
if (!isApproved && !hasBurnRole) revert PermissionDenied();
super._burn(_from, _id, _amount);

}
}

/// @notice Burns token in batch associated with the specified account `_from`
function burnBatch(address _from, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata) external {
function burnBatch(address _from, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata) external {
bool isApproved = isApprovedForAll(_msgSender(), _from);
bool hasBurnRole = isRoleAdmin(BURNER_ROLE) || hasRole(BURNER_ROLE, _msgSender());
if(!isApproved && !hasBurnRole) revert PermissionDenied();
if (!isApproved && !hasBurnRole) revert PermissionDenied();
super._burnBatch(_from, ids, amounts);
}
}

/// @notice Checks that an account has a specified role
/// @param _role The role to query
Expand All @@ -80,7 +81,7 @@ contract MultiChainNativeERC1155 is ERC1155, ERC165Storage, IERC6160Ext1155 {
/// @param _role The role to set for the account
/// @param _account The account to be granted the specified role
function grantRole(bytes32 _role, address _account) external {
if(!isRoleAdmin(_role)) revert NotRoleAdmin();
if (!isRoleAdmin(_role)) revert NotRoleAdmin();
_roles[_role][_account] = true;
}

Expand All @@ -89,28 +90,36 @@ contract MultiChainNativeERC1155 is ERC1155, ERC165Storage, IERC6160Ext1155 {
/// @param _role The role to revoke for the account
/// @param _account The account whose role is to be revoked
function revokeRole(bytes32 _role, address _account) external {
if(!isRoleAdmin(_role)) revert NotRoleAdmin();
if (!isRoleAdmin(_role)) revert NotRoleAdmin();
_roles[_role][_account] = false;
}

/// @notice EIP-165 style to query for supported interfaces
/// @param _interfaceId The interface-id to query for support
function supportsInterface(bytes4 _interfaceId) public view virtual override(ERC1155, ERC165Storage) returns (bool) {
function supportsInterface(bytes4 _interfaceId)
public
view
virtual
override(ERC1155, ERC165Storage)
returns (bool)
{
return super.supportsInterface(_interfaceId);
}

/// @notice Get the Minter-Role ID
function getMinterRole() external pure returns(bytes32) {
function getMinterRole() external pure returns (bytes32) {
return MINTER_ROLE;
}

/// @notice Get the Burner-Role ID
function getBurnerRole() external pure returns(bytes32) {
function getBurnerRole() external pure returns (bytes32) {
return BURNER_ROLE;
}

/** INTERNAL FUNCTIONS **/
function isRoleAdmin(bytes32 role) internal view returns(bool) {
/**
* INTERNAL FUNCTIONS *
*/
function isRoleAdmin(bytes32 role) internal view returns (bool) {
return _rolesAdmin[role][_msgSender()];
}
}
}
35 changes: 18 additions & 17 deletions src/tokens/ERC20.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,30 +27,29 @@ contract MultiChainNativeERC20 is ERC165Storage, ERC20, IERC6160Ext20 {
/// @notice mapping of admins of defined roles
mapping(bytes32 => mapping(address => bool)) _rolesAdmin;

constructor(string memory name, string memory symbol) ERC20(name, symbol) {
constructor(address admin, string memory name, string memory symbol) ERC20(name, symbol) {
_registerInterface(_IERC6160Ext20_ID_);
_registerInterface(type(IERC5679Ext20).interfaceId);
_registerInterface(type(IERC_ACL_CORE).interfaceId);

super._mint(msg.sender, 1_000_000 * 10e18); // 1million initial supply
super._mint(admin, 1_000_000 * 10e18); // 1million initial supply

_rolesAdmin[MINTER_ROLE][msg.sender] = true;
_roles[MINTER_ROLE][msg.sender] = true;
_rolesAdmin[MINTER_ROLE][admin] = true;
_roles[MINTER_ROLE][admin] = true;

_rolesAdmin[BURNER_ROLE][msg.sender] = true;
_roles[BURNER_ROLE][msg.sender] = true;
_rolesAdmin[BURNER_ROLE][admin] = true;
_roles[BURNER_ROLE][admin] = true;
}


/// @notice Mints token to the specified account `_to`
function mint(address _to, uint256 _amount, bytes calldata) external {
if(!isRoleAdmin(MINTER_ROLE) && !hasRole(MINTER_ROLE, _msgSender())) revert PermissionDenied();
if (!isRoleAdmin(MINTER_ROLE) && !hasRole(MINTER_ROLE, _msgSender())) revert PermissionDenied();
super._mint(_to, _amount);
}

/// @notice Burns token associated with the specified account `_from`
function burn(address _from, uint256 _amount, bytes calldata) external {
if(!isRoleAdmin(BURNER_ROLE) && !hasRole(BURNER_ROLE, _msgSender())) revert PermissionDenied();
if (!isRoleAdmin(BURNER_ROLE) && !hasRole(BURNER_ROLE, _msgSender())) revert PermissionDenied();
super._burn(_from, _amount);
}

Expand All @@ -66,7 +65,7 @@ contract MultiChainNativeERC20 is ERC165Storage, ERC20, IERC6160Ext20 {
/// @param _role The role to set for the account
/// @param _account The account to be granted the specified role
function grantRole(bytes32 _role, address _account) external {
if(!isRoleAdmin(_role)) revert NotRoleAdmin();
if (!isRoleAdmin(_role)) revert NotRoleAdmin();
_roles[_role][_account] = true;
}

Expand All @@ -75,28 +74,30 @@ contract MultiChainNativeERC20 is ERC165Storage, ERC20, IERC6160Ext20 {
/// @param _role The role to revoke for the account
/// @param _account The account whose role is to be revoked
function revokeRole(bytes32 _role, address _account) external {
if(!isRoleAdmin(_role)) revert NotRoleAdmin();
if (!isRoleAdmin(_role)) revert NotRoleAdmin();
_roles[_role][_account] = false;
}

/// @notice EIP-165 style to query for supported interfaces
/// @param _interfaceId The interface-id to query for support
function supportsInterface(bytes4 _interfaceId) public view virtual override(ERC165Storage) returns(bool) {
function supportsInterface(bytes4 _interfaceId) public view virtual override(ERC165Storage) returns (bool) {
return super.supportsInterface(_interfaceId);
}

/// @notice Get the Minter-Role ID
function getMinterRole() external pure returns(bytes32) {
function getMinterRole() external pure returns (bytes32) {
return MINTER_ROLE;
}

/// @notice Get the Burner-Role ID
function getBurnerRole() external pure returns(bytes32) {
function getBurnerRole() external pure returns (bytes32) {
return BURNER_ROLE;
}

/** INTERNAL FUNCTIONS **/
function isRoleAdmin(bytes32 role) internal view returns(bool) {
/**
* INTERNAL FUNCTIONS *
*/
function isRoleAdmin(bytes32 role) internal view returns (bool) {
return _rolesAdmin[role][_msgSender()];
}
}
}
Loading

0 comments on commit b41cbbe

Please sign in to comment.