编译器
0.8.24+commit.e11b9ed9
文件 1 的 20:AccessControl.sol
pragma solidity ^0.8.0;
import "./IAccessControl.sol";
import "../utils/Context.sol";
import "../utils/Strings.sol";
import "../utils/introspection/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);
_;
}
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) internal view virtual {
_checkRole(role, _msgSender());
}
function _checkRole(bytes32 role, address account) internal view virtual {
if (!hasRole(role, account)) {
revert(
string(
abi.encodePacked(
"AccessControl: account ",
Strings.toHexString(account),
" 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 的 20:AccountControl.sol
pragma solidity ^0.8.17;
import "./RoleManager.sol";
import "./ArrayLimiter.sol";
abstract contract AccountControl is ArrayLimiter, RoleManager {
mapping(address => bool) private _frozen;
mapping(address => bool) private _whitelist;
mapping(address => bool) private _greylist;
event AccountFrozen(address indexed account);
event AccountUnFrozen(address indexed account);
event AccountWhitelisted(address indexed account);
event AccountUnWhitelisted(address indexed account);
event AccountGreylisted(address indexed account);
event AccountUnGreylisted(address indexed account);
modifier accNotListed(address account) {
require(!isAccountFrozen(account), "AC: Account already frozen");
require(!isWhitelisted(account), "AC: Account already whitelisted");
require(!isGreylisted(account), "AC: Account already greylisted");
_;
}
function freezeAccount(address account)
external
onlyRole(ISSUER_ROLE)
isNotZeroAddress(account)
accNotListed(account)
{
_frozen[account] = true;
emit AccountFrozen(account);
}
function unFreezeAccount(address account) external onlyRole(ISSUER_ROLE) {
require(isAccountFrozen(account), "AC: Account not frozen");
_frozen[account] = false;
emit AccountUnFrozen(account);
}
function isAccountFrozen(address account) public view returns (bool) {
return _frozen[account];
}
function frozenInArray(address[] calldata accounts) public view returns (address[] memory frozen) {
address[] calldata _accounts = accounts;
frozen = new address[](_accounts.length);
uint256 frozenCounter = 0;
for (uint256 i = 0; i < _accounts.length; i++) {
if (isAccountFrozen(_accounts[i])) {
frozen[frozenCounter] = _accounts[i];
frozenCounter++;
}
}
}
function whitelistAccount(address account)
public
onlyRole(ISSUER_ROLE)
isNotZeroAddress(account)
accNotListed(account)
{
_whitelist[account] = true;
emit AccountWhitelisted(account);
}
function bulkWhitelistAccount(address[] calldata accounts) external arrayMaxSize(accounts.length) {
address[] calldata _accounts = accounts;
for (uint256 i = 0; i < _accounts.length; i++) {
whitelistAccount(_accounts[i]);
}
}
function unWhitelistAccount(address account) public onlyRole(ISSUER_ROLE) {
require(isWhitelisted(account), "AC: Account not whitelisted");
delete _whitelist[account];
emit AccountUnWhitelisted(account);
}
function bulkUnWhitelistAccount(address[] calldata accounts) external arrayMaxSize(accounts.length) {
address[] calldata _accounts = accounts;
for (uint256 i = 0; i < _accounts.length; i++) {
unWhitelistAccount(_accounts[i]);
}
}
function isWhitelisted(address account) public view returns (bool) {
return _whitelist[account];
}
function whitelistedInArray(address[] calldata accounts) public view returns (address[] memory whitelisted) {
address[] calldata _accounts = accounts;
whitelisted = new address[](_accounts.length);
uint256 whitelistedCounter = 0;
for (uint256 i = 0; i < _accounts.length; i++) {
if (isWhitelisted(_accounts[i])) {
whitelisted[whitelistedCounter] = _accounts[i];
whitelistedCounter++;
}
}
}
function greylistAccount(address account)
public
onlyRole(ISSUER_ROLE)
isNotZeroAddress(account)
accNotListed(account)
{
_greylist[account] = true;
emit AccountGreylisted(account);
}
function bulkGreylistAccount(address[] calldata accounts) external arrayMaxSize(accounts.length) {
address[] calldata _accounts = accounts;
for (uint256 i = 0; i < _accounts.length; i++) {
greylistAccount(_accounts[i]);
}
}
function unGreylistAccount(address account) public onlyRole(ISSUER_ROLE) {
require(isGreylisted(account), "AC: Account not greylisted");
delete _greylist[account];
emit AccountUnGreylisted(account);
}
function bulkUnGreylistAccount(address[] calldata accounts) external arrayMaxSize(accounts.length) {
address[] calldata _accounts = accounts;
for (uint256 i = 0; i < _accounts.length; i++) {
unGreylistAccount(_accounts[i]);
}
}
function isGreylisted(address account) public view returns (bool) {
return _greylist[account];
}
function greylistedInArray(address[] calldata accounts) public view returns (address[] memory greylisted) {
address[] calldata _accounts = accounts;
greylisted = new address[](_accounts.length);
uint256 greylistedCounter = 0;
for (uint256 i = 0; i < _accounts.length; i++) {
if (isGreylisted(_accounts[i])) {
greylisted[greylistedCounter] = _accounts[i];
greylistedCounter++;
}
}
}
}
文件 3 的 20:Address.sol
pragma solidity ^0.8.1;
library Address {
function isContract(address account) internal view returns (bool) {
return account.code.length > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
文件 4 的 20:ArrayLimiter.sol
pragma solidity ^0.8.17;
abstract contract ArrayLimiter {
event NewMaxArraySizeSet(uint256 newMaxArraySize);
uint256 public maxArraySize = 20;
modifier arrayMaxSize(uint256 arraySize) {
require(arraySize <= maxArraySize, "AL: Array size must be <= maxArraySize");
_;
}
function _setMaxArraySize(uint256 _maxArraySize) internal {
maxArraySize = _maxArraySize;
emit NewMaxArraySizeSet(_maxArraySize);
}
}
文件 5 的 20:AuthorizeManager.sol
pragma solidity ^0.8.17;
import "./interfaces/IAuthorizationContract.sol";
abstract contract AuthorizeManager {
mapping(uint256 => address) private authorizeContracts;
address public globalAuthContract;
event GlobalAuthContractSet(address from, address authContract);
event TokenAuthContractSet(address from, uint256 indexed id, address authContract);
function mustBeAuthorizedHolder(
address _address,
uint256 _id,
bytes memory
) public view returns (bool) {
address authContract = authorizeContracts[_id];
if (authContract == address(0)) authContract = globalAuthContract;
if (authContract == address(0)) return false;
try IAuthorizationContract(authContract).isAccountAuthorized(_address) returns (bool response) {
return response;
} catch Error(string memory) {
return false;
} catch {
return false;
}
}
function mustBeAuthorizedHolders(
address _from,
address _to,
uint256 _id,
bytes memory _data
) public view returns (bool) {
return (mustBeAuthorizedHolder(_from, _id, _data) && mustBeAuthorizedHolder(_to, _id, _data));
}
function _setDefaultAuthorizationContract(address authContract) internal {
if (authContract != address(0)) require(_isContract(authContract), "AM: Not a valid auth contract address");
globalAuthContract = authContract;
emit GlobalAuthContractSet(msg.sender, authContract);
}
function _setAuthorizationContract(uint256 id, address authContract) internal {
if (authContract != address(0)) require(_isContract(authContract), "AM: Not a valid auth contract address");
authorizeContracts[id] = authContract;
emit TokenAuthContractSet(msg.sender, id, authContract);
}
function _isContract(address _contractAddress) internal view returns (bool) {
return _contractAddress.code.length > 0;
}
}
文件 6 的 20: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;
}
}
文件 7 的 20:ERC1155.sol
pragma solidity ^0.8.0;
import "./IERC1155.sol";
import "./IERC1155Receiver.sol";
import "./extensions/IERC1155MetadataURI.sol";
import "../../utils/Address.sol";
import "../../utils/Context.sol";
import "../../utils/introspection/ERC165.sol";
contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
using Address for address;
mapping(uint256 => mapping(address => uint256)) private _balances;
mapping(address => mapping(address => bool)) private _operatorApprovals;
string private _uri;
constructor(string memory uri_) {
_setURI(uri_);
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return
interfaceId == type(IERC1155).interfaceId ||
interfaceId == type(IERC1155MetadataURI).interfaceId ||
super.supportsInterface(interfaceId);
}
function uri(uint256) public view virtual override returns (string memory) {
return _uri;
}
function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {
require(account != address(0), "ERC1155: address zero is not a valid owner");
return _balances[id][account];
}
function balanceOfBatch(address[] memory accounts, uint256[] memory ids)
public
view
virtual
override
returns (uint256[] memory)
{
require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch");
uint256[] memory batchBalances = new uint256[](accounts.length);
for (uint256 i = 0; i < accounts.length; ++i) {
batchBalances[i] = balanceOf(accounts[i], ids[i]);
}
return batchBalances;
}
function setApprovalForAll(address operator, bool approved) public virtual override {
_setApprovalForAll(_msgSender(), operator, approved);
}
function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {
return _operatorApprovals[account][operator];
}
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) public virtual override {
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
"ERC1155: caller is not token owner or approved"
);
_safeTransferFrom(from, to, id, amount, data);
}
function safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) public virtual override {
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
"ERC1155: caller is not token owner or approved"
);
_safeBatchTransferFrom(from, to, ids, amounts, data);
}
function _safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) internal virtual {
require(to != address(0), "ERC1155: transfer to the zero address");
address operator = _msgSender();
uint256[] memory ids = _asSingletonArray(id);
uint256[] memory amounts = _asSingletonArray(amount);
_beforeTokenTransfer(operator, from, to, ids, amounts, data);
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
unchecked {
_balances[id][from] = fromBalance - amount;
}
_balances[id][to] += amount;
emit TransferSingle(operator, from, to, id, amount);
_afterTokenTransfer(operator, from, to, ids, amounts, data);
_doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);
}
function _safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
require(to != address(0), "ERC1155: transfer to the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, from, to, ids, amounts, data);
for (uint256 i = 0; i < ids.length; ++i) {
uint256 id = ids[i];
uint256 amount = amounts[i];
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
unchecked {
_balances[id][from] = fromBalance - amount;
}
_balances[id][to] += amount;
}
emit TransferBatch(operator, from, to, ids, amounts);
_afterTokenTransfer(operator, from, to, ids, amounts, data);
_doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);
}
function _setURI(string memory newuri) internal virtual {
_uri = newuri;
}
function _mint(
address to,
uint256 id,
uint256 amount,
bytes memory data
) internal virtual {
require(to != address(0), "ERC1155: mint to the zero address");
address operator = _msgSender();
uint256[] memory ids = _asSingletonArray(id);
uint256[] memory amounts = _asSingletonArray(amount);
_beforeTokenTransfer(operator, address(0), to, ids, amounts, data);
_balances[id][to] += amount;
emit TransferSingle(operator, address(0), to, id, amount);
_afterTokenTransfer(operator, address(0), to, ids, amounts, data);
_doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);
}
function _mintBatch(
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {
require(to != address(0), "ERC1155: mint to the zero address");
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
address operator = _msgSender();
_beforeTokenTransfer(operator, address(0), to, ids, amounts, data);
for (uint256 i = 0; i < ids.length; i++) {
_balances[ids[i]][to] += amounts[i];
}
emit TransferBatch(operator, address(0), to, ids, amounts);
_afterTokenTransfer(operator, address(0), to, ids, amounts, data);
_doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);
}
function _burn(
address from,
uint256 id,
uint256 amount
) internal virtual {
require(from != address(0), "ERC1155: burn from the zero address");
address operator = _msgSender();
uint256[] memory ids = _asSingletonArray(id);
uint256[] memory amounts = _asSingletonArray(amount);
_beforeTokenTransfer(operator, from, address(0), ids, amounts, "");
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
unchecked {
_balances[id][from] = fromBalance - amount;
}
emit TransferSingle(operator, from, address(0), id, amount);
_afterTokenTransfer(operator, from, address(0), ids, amounts, "");
}
function _burnBatch(
address from,
uint256[] memory ids,
uint256[] memory amounts
) internal virtual {
require(from != address(0), "ERC1155: burn from the zero address");
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
address operator = _msgSender();
_beforeTokenTransfer(operator, from, address(0), ids, amounts, "");
for (uint256 i = 0; i < ids.length; i++) {
uint256 id = ids[i];
uint256 amount = amounts[i];
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
unchecked {
_balances[id][from] = fromBalance - amount;
}
}
emit TransferBatch(operator, from, address(0), ids, amounts);
_afterTokenTransfer(operator, from, address(0), ids, amounts, "");
}
function _setApprovalForAll(
address owner,
address operator,
bool approved
) internal virtual {
require(owner != operator, "ERC1155: setting approval status for self");
_operatorApprovals[owner][operator] = approved;
emit ApprovalForAll(owner, operator, approved);
}
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {}
function _afterTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {}
function _doSafeTransferAcceptanceCheck(
address operator,
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) private {
if (to.isContract()) {
try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {
if (response != IERC1155Receiver.onERC1155Received.selector) {
revert("ERC1155: ERC1155Receiver rejected tokens");
}
} catch Error(string memory reason) {
revert(reason);
} catch {
revert("ERC1155: transfer to non-ERC1155Receiver implementer");
}
}
}
function _doSafeBatchTransferAcceptanceCheck(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) private {
if (to.isContract()) {
try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (
bytes4 response
) {
if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {
revert("ERC1155: ERC1155Receiver rejected tokens");
}
} catch Error(string memory reason) {
revert(reason);
} catch {
revert("ERC1155: transfer to non-ERC1155Receiver implementer");
}
}
}
function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {
uint256[] memory array = new uint256[](1);
array[0] = element;
return array;
}
}
文件 8 的 20:ERC165.sol
pragma solidity ^0.8.0;
import "./IERC165.sol";
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
文件 9 的 20: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;
}
文件 10 的 20:IAuthorizationContract.sol
pragma solidity ^0.8.17;
interface IAuthorizationContract {
function isAccountAuthorized(address _to) external view returns (bool);
}
文件 11 的 20:IERC1155.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
interface IERC1155 is IERC165 {
event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);
event TransferBatch(
address indexed operator,
address indexed from,
address indexed to,
uint256[] ids,
uint256[] values
);
event ApprovalForAll(address indexed account, address indexed operator, bool approved);
event URI(string value, uint256 indexed id);
function balanceOf(address account, uint256 id) external view returns (uint256);
function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
external
view
returns (uint256[] memory);
function setApprovalForAll(address operator, bool approved) external;
function isApprovedForAll(address account, address operator) external view returns (bool);
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes calldata data
) external;
function safeBatchTransferFrom(
address from,
address to,
uint256[] calldata ids,
uint256[] calldata amounts,
bytes calldata data
) external;
}
文件 12 的 20:IERC1155MetadataURI.sol
pragma solidity ^0.8.0;
import "../IERC1155.sol";
interface IERC1155MetadataURI is IERC1155 {
function uri(uint256 id) external view returns (string memory);
}
文件 13 的 20:IERC1155Receiver.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
interface IERC1155Receiver is IERC165 {
function onERC1155Received(
address operator,
address from,
uint256 id,
uint256 value,
bytes calldata data
) external returns (bytes4);
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
) external returns (bytes4);
}
文件 14 的 20:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 15 的 20:Math.sol
pragma solidity ^0.8.0;
library Math {
enum Rounding {
Down,
Up,
Zero
}
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
function average(uint256 a, uint256 b) internal pure returns (uint256) {
return (a & b) + (a ^ b) / 2;
}
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
return a == 0 ? 0 : (a - 1) / b + 1;
}
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 result) {
unchecked {
uint256 prod0;
uint256 prod1;
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
if (prod1 == 0) {
return prod0 / denominator;
}
require(denominator > prod1);
uint256 remainder;
assembly {
remainder := mulmod(x, y, denominator)
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
uint256 twos = denominator & (~denominator + 1);
assembly {
denominator := div(denominator, twos)
prod0 := div(prod0, twos)
twos := add(div(sub(0, twos), twos), 1)
}
prod0 |= prod1 * twos;
uint256 inverse = (3 * denominator) ^ 2;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
result = prod0 * inverse;
return result;
}
}
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator,
Rounding rounding
) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 result = 1 << (log2(a) >> 1);
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10**64) {
value /= 10**64;
result += 64;
}
if (value >= 10**32) {
value /= 10**32;
result += 32;
}
if (value >= 10**16) {
value /= 10**16;
result += 16;
}
if (value >= 10**8) {
value /= 10**8;
result += 8;
}
if (value >= 10**4) {
value /= 10**4;
result += 4;
}
if (value >= 10**2) {
value /= 10**2;
result += 2;
}
if (value >= 10**1) {
result += 1;
}
}
return result;
}
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);
}
}
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
}
}
}
文件 16 的 20:Pausable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Pausable is Context {
event Paused(address account);
event Unpaused(address account);
bool private _paused;
constructor() {
_paused = false;
}
modifier whenNotPaused() {
_requireNotPaused();
_;
}
modifier whenPaused() {
_requirePaused();
_;
}
function paused() public view virtual returns (bool) {
return _paused;
}
function _requireNotPaused() internal view virtual {
require(!paused(), "Pausable: paused");
}
function _requirePaused() internal view virtual {
require(paused(), "Pausable: not paused");
}
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
文件 17 的 20:RoleManager.sol
pragma solidity ^0.8.17;
import "@openzeppelin/contracts/access/AccessControl.sol";
abstract contract RoleManager is AccessControl {
bytes32 public constant ISSUER_ROLE = keccak256("ISSUER");
bytes32 public constant EDITOR_ROLE = keccak256("EDITOR");
bytes32 public constant AGENT_ROLE = keccak256("AGENT");
modifier isNotZeroAddress(address account) {
require(account != address(0), "Passed address = zero address");
_;
}
constructor(
address admin,
address issuer,
address editor
) isNotZeroAddress(admin) isNotZeroAddress(issuer) isNotZeroAddress(editor) {
_grantRole(DEFAULT_ADMIN_ROLE, admin);
_grantRole(ISSUER_ROLE, issuer);
_grantRole(EDITOR_ROLE, editor);
}
function grantRole(bytes32 role, address account) public override onlyRole(DEFAULT_ADMIN_ROLE) {
_grantRole(role, account);
}
function revokeRole(bytes32 role, address account) public override onlyRole(DEFAULT_ADMIN_ROLE) {
_revokeRole(role, account);
}
function grantEditorRole(address to) external onlyRole(ISSUER_ROLE) {
_grantRole(EDITOR_ROLE, to);
}
function revokeEditorRole(address account) external onlyRole(ISSUER_ROLE) {
_revokeRole(EDITOR_ROLE, account);
}
function grantIssuerRole(address to) external onlyRole(ISSUER_ROLE) {
_grantRole(ISSUER_ROLE, to);
}
function revokeIssuerRole(address account) external onlyRole(ISSUER_ROLE) {
_revokeRole(ISSUER_ROLE, account);
}
function grantAgentRole(address to) external onlyRole(ISSUER_ROLE) {
_grantRole(AGENT_ROLE, to);
}
function revokeAgentRole(address account) external onlyRole(ISSUER_ROLE) {
_revokeRole(AGENT_ROLE, account);
}
function supportsInterface(bytes4 interfaceId) public view virtual override(AccessControl) returns (bool) {
return super.supportsInterface(interfaceId);
}
function _grantRole(bytes32 role, address account) internal override isNotZeroAddress(account) {
require(!hasRole(role, account), "RM: Account already has role");
super._grantRole(role, account);
}
function _revokeRole(bytes32 role, address account) internal override {
require(hasRole(role, account), "RM: Account has no role");
require(msg.sender != account, "RM: You can't revoke your role");
super._revokeRole(role, account);
}
}
文件 18 的 20:SX1155NFT.sol
pragma solidity ^0.8.17;
import "@openzeppelin/contracts/security/Pausable.sol";
import "./SX1155NFTBase.sol";
import "./RoleManager.sol";
import "./AuthorizeManager.sol";
import "./AccountControl.sol";
contract SX1155NFT is Pausable, SX1155NFTBase, RoleManager, AuthorizeManager, AccountControl {
struct GreylistTransferRequest {
address from;
address to;
uint256 tokenId;
uint256 quantity;
bool valid;
}
uint256 greylistNextReqId = 1;
mapping(uint256 => GreylistTransferRequest) internal greylistTransferRequests;
event ForceTransfer(address indexed issuer, address indexed from, address indexed to, uint256 tokenId);
event ForceBurn(address indexed issuer, address indexed from, uint256 indexed tokenId, string reason);
event GreylistTransferRequestCreated(
uint256 indexed reqId,
address indexed from,
address indexed to,
uint256 tokenId,
uint256 quantity
);
event GreylistTransferApproved(uint256 indexed reqId, address indexed issuer, uint256 indexed tokenId);
event GreylistTransferCancelled(uint256 indexed reqId, address indexed from, address indexed to, uint256 tokenId);
constructor(
string memory _name,
string memory _symbol,
address _admin,
address _issuer,
address _editor
) SX1155NFTBase(_name, _symbol) RoleManager(_admin, _issuer, _editor) {}
function setKya(string calldata _kya) external onlyRole(EDITOR_ROLE) {
_setKya(_kya);
}
function setTokenKya(uint256 _id, string calldata _kya) external onlyRole(EDITOR_ROLE) {
_setTokenKya(_id, _kya);
}
function setContractURI(string calldata _contract_uri) external onlyRole(ISSUER_ROLE) {
_setContractURI(_contract_uri);
}
function pauseToken() external onlyRole(ISSUER_ROLE) {
_pause();
}
function unPauseToken() external onlyRole(ISSUER_ROLE) {
_unpause();
}
function setTokenAuthContract(uint256 _id, address _authContract) external onlyRole(AGENT_ROLE) {
_setAuthorizationContract(_id, _authContract);
}
function setGlobalAuthContract(address _authContract) external onlyRole(AGENT_ROLE) {
_setDefaultAuthorizationContract(_authContract);
}
function setMaxArraySize(uint256 _maxArraySize) external onlyRole(ISSUER_ROLE) {
_setMaxArraySize(_maxArraySize);
}
function approveTransferRequest(uint256 reqId) external onlyRole(ISSUER_ROLE) {
GreylistTransferRequest memory req = greylistTransferRequests[reqId];
require(req.valid, "SX1155: Invalid request id");
delete greylistTransferRequests[reqId];
_safeTransferFrom(req.from, req.to, req.tokenId, req.quantity, "");
emit GreylistTransferApproved(reqId, msg.sender, req.tokenId);
}
function cancelTransferRequest(uint256 reqId) external {
GreylistTransferRequest memory req = greylistTransferRequests[reqId];
require(req.valid, "SX1155: Invalid request id");
require(req.from == msg.sender, "SX1155: Sender is not owner of the transfer request");
delete greylistTransferRequests[reqId];
emit GreylistTransferCancelled(reqId, req.from, req.to, req.tokenId);
}
function requestTransfer(
address to,
uint256 tokenId,
uint256 quantity
) external isNotZeroAddress(to) returns (uint256 reqId) {
_requireNotPaused();
if (isAccountFrozen(msg.sender) || isAccountFrozen(to)) revert("SX1155: Sender or receiver account frozen");
require(isGreylisted(msg.sender) || isGreylisted(to), "SX1155: Account not in greylist");
reqId = greylistNextReqId;
greylistTransferRequests[reqId] = GreylistTransferRequest(msg.sender, to, tokenId, quantity, true);
greylistNextReqId++;
emit GreylistTransferRequestCreated(reqId, msg.sender, to, tokenId, quantity);
return reqId;
}
function supportsInterface(bytes4 _interfaceId) public view override(SX1155NFTBase, RoleManager) returns (bool) {
return super.supportsInterface(_interfaceId);
}
function transferRequestInfo(uint256 reqId)
external
view
returns (
address from,
address to,
uint256 tokenId,
uint256 quantity
)
{
return (
greylistTransferRequests[reqId].from,
greylistTransferRequests[reqId].to,
greylistTransferRequests[reqId].tokenId,
greylistTransferRequests[reqId].quantity
);
}
function mint(
address _to,
uint256 _quantity,
string calldata _tokenURI,
bytes calldata _data
) public onlyRole(ISSUER_ROLE) {
_mintToken(_to, _quantity, _tokenURI, _data);
}
function mintBatch(
address[] calldata _accounts,
uint256[] calldata _quantities,
string[] calldata _tokenURIs,
bytes[] calldata _data
) external arrayMaxSize(_accounts.length) {
require(
_accounts.length == _quantities.length &&
_accounts.length == _tokenURIs.length &&
_accounts.length == _data.length,
"SX1155: Invalid inputs"
);
uint256 accountsLength = _accounts.length;
for (uint256 i = 0; i < accountsLength; i++) {
mint(_accounts[i], _quantities[i], _tokenURIs[i], _data[i]);
}
}
function burn(uint256 _id, uint256 _quantity) external {
_burnToken(msg.sender, _id, _quantity);
}
function forceBurn(
address from,
uint256 tokenId,
uint256 quantity,
string calldata reason
) public onlyRole(ISSUER_ROLE) {
_burnToken(from, tokenId, quantity);
emit ForceBurn(msg.sender, from, tokenId, reason);
}
function forceBurnBatch(
address[] calldata _accounts,
uint256[] calldata _tokenIds,
uint256[] calldata _quantities,
string calldata reason
) external arrayMaxSize(_accounts.length) {
require(
_accounts.length == _tokenIds.length && _accounts.length == _quantities.length,
"SX1155: Invalid inputs"
);
uint256 accountsLength = _accounts.length;
for (uint256 i = 0; i < accountsLength; i++) {
forceBurn(_accounts[i], _tokenIds[i], _quantities[i], reason);
}
}
function forceTransfer(
address from,
address to,
uint256 tokenId,
uint256 quantity
) external onlyRole(ISSUER_ROLE) {
_safeTransferFrom(from, to, tokenId, quantity, "");
emit ForceTransfer(msg.sender, from, to, tokenId);
}
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory quantities,
bytes memory data
) internal override {
uint256 i;
super._beforeTokenTransfer(operator, from, to, ids, quantities, data);
if (hasRole(ISSUER_ROLE, msg.sender)) return;
_requireNotPaused();
if (isAccountFrozen(from) || isAccountFrozen(to)) revert("SX1155: Sender or receiver account frozen");
if (isGreylisted(from) || isGreylisted(to))
revert("SX1155: Sender or receiver are greylisted. Use requestTransfer");
bool senderWhitelisted = isWhitelisted(from);
bool receiverWhitelisted = isWhitelisted(to);
if (senderWhitelisted && receiverWhitelisted) return;
uint256 idsLength = ids.length;
if (to != address(0)) {
if (!senderWhitelisted && !receiverWhitelisted) {
for (i = 0; i < idsLength; i++) {
require(mustBeAuthorizedHolders(from, to, ids[i], data), "SX1155: Not authorized");
}
} else if (senderWhitelisted) {
for (i = 0; i < idsLength; i++) {
require(mustBeAuthorizedHolder(to, ids[i], data), "SX1155: receiver is not authorized");
}
} else {
for (i = 0; i < idsLength; i++) {
require(mustBeAuthorizedHolder(from, ids[i], data), "SX1155: sender is not authorized");
}
}
}
}
}
文件 19 的 20:SX1155NFTBase.sol
pragma solidity ^0.8.17;
import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
contract SX1155NFTBase is ERC1155 {
string public kya;
mapping(uint256 => string) public tokenKya;
mapping(uint256 => uint256) private tokenSupply;
string public contractURI;
mapping(uint256 => string) private tokenURIs;
string public name;
string public symbol;
uint256 public currentTokenId = 1;
event KyaUpdated(address from, string kya);
event TokenKyaUpdated(address from, uint256 indexed id, string kya);
event ContractURISet(address from, string uri);
constructor(string memory _name, string memory _symbol) ERC1155("") {
name = _name;
symbol = _symbol;
}
function supportsInterface(bytes4 _interfaceId) public view virtual override(ERC1155) returns (bool) {
return super.supportsInterface(_interfaceId);
}
function uri(uint256 _id) public view override returns (string memory) {
return tokenURIs[_id];
}
function totalSupply(uint256 _id) external view returns (uint256) {
return tokenSupply[_id];
}
function _setKya(string calldata _kya) internal {
kya = _kya;
emit KyaUpdated(msg.sender, _kya);
}
function _setTokenKya(uint256 _id, string calldata _kya) internal {
require(tokenSupply[_id] > 0, "SX1155: Token does not exist");
tokenKya[_id] = _kya;
emit TokenKyaUpdated(msg.sender, _id, _kya);
}
function _setContractURI(string calldata _contract_uri) internal {
require(bytes(contractURI).length == 0, "SX1155: Already set");
contractURI = _contract_uri;
emit ContractURISet(msg.sender, _contract_uri);
}
function _mintToken(
address _to,
uint256 _quantity,
string calldata _tokenURI,
bytes calldata _data
) internal {
require(_quantity > 0, "SX1155: Invalid quantity");
uint256 _id = currentTokenId;
tokenURIs[_id] = _tokenURI;
tokenSupply[_id] = _quantity;
currentTokenId++;
_mint(_to, _id, _quantity, _data);
}
function _burnToken(
address from,
uint256 _id,
uint256 _quantity
) internal {
tokenSupply[_id] -= _quantity;
if (tokenSupply[_id] == 0) {
delete tokenURIs[_id];
delete tokenKya[_id];
}
_burn(from, _id, _quantity);
}
}
文件 20 的 20:Strings.sol
pragma solidity ^0.8.0;
import "./math/Math.sol";
library Strings {
bytes16 private constant _SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = Math.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
assembly {
mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, Math.log256(value) + 1);
}
}
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] = _SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
}
{
"compilationTarget": {
"contracts/SX1155NFT.sol": "SX1155NFT"
},
"evmVersion": "shanghai",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"address","name":"_admin","type":"address"},{"internalType":"address","name":"_issuer","type":"address"},{"internalType":"address","name":"_editor","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"AccountFrozen","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"AccountGreylisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"AccountUnFrozen","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"AccountUnGreylisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"AccountUnWhitelisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"AccountWhitelisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"string","name":"uri","type":"string"}],"name":"ContractURISet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"issuer","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"string","name":"reason","type":"string"}],"name":"ForceBurn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"issuer","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ForceTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"address","name":"authContract","type":"address"}],"name":"GlobalAuthContractSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"reqId","type":"uint256"},{"indexed":true,"internalType":"address","name":"issuer","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"GreylistTransferApproved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"reqId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"GreylistTransferCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"reqId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"GreylistTransferRequestCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"string","name":"kya","type":"string"}],"name":"KyaUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newMaxArraySize","type":"uint256"}],"name":"NewMaxArraySizeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"address","name":"authContract","type":"address"}],"name":"TokenAuthContractSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"string","name":"kya","type":"string"}],"name":"TokenKyaUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"AGENT_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":[],"name":"EDITOR_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ISSUER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"reqId","type":"uint256"}],"name":"approveTransferRequest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"}],"name":"bulkGreylistAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"}],"name":"bulkUnGreylistAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"}],"name":"bulkUnWhitelistAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"}],"name":"bulkWhitelistAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint256","name":"_quantity","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"reqId","type":"uint256"}],"name":"cancelTransferRequest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"string","name":"reason","type":"string"}],"name":"forceBurn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_accounts","type":"address[]"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"uint256[]","name":"_quantities","type":"uint256[]"},{"internalType":"string","name":"reason","type":"string"}],"name":"forceBurnBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"forceTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"freezeAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"}],"name":"frozenInArray","outputs":[{"internalType":"address[]","name":"frozen","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"globalAuthContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"grantAgentRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"grantEditorRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"grantIssuerRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"greylistAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"}],"name":"greylistedInArray","outputs":[{"internalType":"address[]","name":"greylisted","type":"address[]"}],"stateMutability":"view","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":"account","type":"address"}],"name":"isAccountFrozen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isGreylisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"kya","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxArraySize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_quantity","type":"uint256"},{"internalType":"string","name":"_tokenURI","type":"string"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_accounts","type":"address[]"},{"internalType":"uint256[]","name":"_quantities","type":"uint256[]"},{"internalType":"string[]","name":"_tokenURIs","type":"string[]"},{"internalType":"bytes[]","name":"_data","type":"bytes[]"}],"name":"mintBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"mustBeAuthorizedHolder","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"mustBeAuthorizedHolders","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pauseToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"requestTransfer","outputs":[{"internalType":"uint256","name":"reqId","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"revokeAgentRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"revokeEditorRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"revokeIssuerRole","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":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_contract_uri","type":"string"}],"name":"setContractURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_authContract","type":"address"}],"name":"setGlobalAuthContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_kya","type":"string"}],"name":"setKya","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxArraySize","type":"uint256"}],"name":"setMaxArraySize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"address","name":"_authContract","type":"address"}],"name":"setTokenAuthContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"string","name":"_kya","type":"string"}],"name":"setTokenKya","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenKya","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"reqId","type":"uint256"}],"name":"transferRequestInfo","outputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"unFreezeAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"unGreylistAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unPauseToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"unWhitelistAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"whitelistAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"}],"name":"whitelistedInArray","outputs":[{"internalType":"address[]","name":"whitelisted","type":"address[]"}],"stateMutability":"view","type":"function"}]