54 lines
1.5 KiB
Solidity
54 lines
1.5 KiB
Solidity
|
// SPDX-License-Identifier: CC0-1.0
|
||
|
|
||
|
pragma solidity ^0.8.0;
|
||
|
|
||
|
import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
|
||
|
import "./IERC5633.sol";
|
||
|
|
||
|
/**
|
||
|
* @dev Extension of ERC1155 that adds soulbound property per token id.
|
||
|
*
|
||
|
*/
|
||
|
abstract contract ERC5633 is ERC1155, IERC5633 {
|
||
|
mapping(uint256 => bool) private _soulbounds;
|
||
|
|
||
|
/// @dev See {IERC165-supportsInterface}.
|
||
|
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC1155) returns (bool) {
|
||
|
return interfaceId == type(IERC5633).interfaceId || super.supportsInterface(interfaceId);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @dev Returns true if a token type `id` is soulbound.
|
||
|
*/
|
||
|
function isSoulbound(uint256 id) public view virtual returns (bool) {
|
||
|
return _soulbounds[id];
|
||
|
}
|
||
|
|
||
|
function _setSoulbound(uint256 id, bool soulbound) internal {
|
||
|
_soulbounds[id] = soulbound;
|
||
|
emit Soulbound(id, soulbound);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @dev See {ERC1155-_beforeTokenTransfer}.
|
||
|
*/
|
||
|
function _beforeTokenTransfer(
|
||
|
address operator,
|
||
|
address from,
|
||
|
address to,
|
||
|
uint256[] memory ids,
|
||
|
uint256[] memory amounts,
|
||
|
bytes memory data
|
||
|
) internal virtual override {
|
||
|
super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
|
||
|
|
||
|
for (uint256 i = 0; i < ids.length; ++i) {
|
||
|
if (isSoulbound(ids[i])) {
|
||
|
require(
|
||
|
from == address(0) || to == address(0),
|
||
|
"ERC5633: Soulbound, Non-Transferable"
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|