// SPDX-License-Identifier: UNLICENSED pragma solidity =0.8.18; import "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol"; import "contracts/soma/SomaGuard/utils/GuardableUpgradeable.sol"; import "./IERC721Guard.sol"; /** * @notice Implementation of the {IERC721Guard} interface. */ abstract contract ERC721Guard is IERC721Guard, ERC721Upgradeable, GuardableUpgradeable { /** * @notice Initializer for extended contracts. */ function __ERC721Guard_init() internal onlyInitializing { __ERC165_init_unchained(); __Context_init_unchained(); __Guardable__init_unchained(); __SomaContract_init_unchained(); __Accessible_init_unchained(); __Multicall_init_unchained(); __Pausable_init_unchained(); __ERC721Guard_init_unchained(); } /** * @notice Unchained initializer. */ function __ERC721Guard_init_unchained() internal onlyInitializing {} /** * @inheritdoc IERC721Guard */ function canTransferFrom(address _from, address _to, uint256) public view virtual returns (bool) { ISomaGuard _guard = ISomaGuard(SOMA.guard()); bytes32 _privileges = requiredPrivileges(); // if the from address is 0 then it is minting // if the to address is 0 then it is burning // in both scenarios, we want to assume that address(0) is allowed. return (_from == address(0) || _guard.check(_from, _privileges)) && (_to == address(0) || _guard.check(_to, _privileges)); } /** * @notice Checks if ERC721Guard inherits a given contract interface. * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721Upgradeable, GuardableUpgradeable) returns (bool) { return interfaceId == type(IERC721Guard).interfaceId || super.supportsInterface(interfaceId); } function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual override { super._beforeTokenTransfer(from, to, tokenId); // ignore checks if bypass is true if (_bypassValidate()) return; // SomaGuard check, for determining if each user has the requiredPrivileges for this security require(canTransferFrom(from, to, tokenId), "ERC721Guard: MISSING_PRIVILEGES"); } function _bypassValidate() internal virtual returns (bool) { return false; } uint256[50] private __gap; }