diff --git a/contracts/interfaces/tokens/ISBT.sol b/contracts/interfaces/tokens/ISBT.sol index 8a29d8ec..251addab 100644 --- a/contracts/interfaces/tokens/ISBT.sol +++ b/contracts/interfaces/tokens/ISBT.sol @@ -5,8 +5,7 @@ pragma solidity ^0.8.4; * @notice The SBT module */ interface ISBT { - event Minted(address to, uint256 tokenId); - event Burned(address from, uint256 tokenId); + event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); function name() external view returns (string memory); diff --git a/contracts/package.json b/contracts/package.json index 1cb041c0..67f2a730 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -1,6 +1,6 @@ { "name": "@solarity/solidity-lib", - "version": "2.6.1", + "version": "2.6.2", "license": "MIT", "author": "Distributed Lab", "readme": "README.md", diff --git a/contracts/tokens/SBT.sol b/contracts/tokens/SBT.sol index 3aa73dcd..586d8a34 100644 --- a/contracts/tokens/SBT.sol +++ b/contracts/tokens/SBT.sol @@ -1,7 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.4; -import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; +import {ERC165Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol"; +import {IERC721Metadata} from "@openzeppelin/contracts/interfaces/IERC721Metadata.sol"; import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; @@ -15,7 +16,7 @@ import {ISBT} from "../interfaces/tokens/ISBT.sol"; * * Has to be inherited in order to be useful in the project */ -abstract contract SBT is ISBT, Initializable { +abstract contract SBT is ISBT, ERC165Upgradeable { using Strings for uint256; using EnumerableSet for EnumerableSet.UintSet; @@ -134,6 +135,18 @@ abstract contract SBT is ISBT, Initializable { return ""; } + /** + * @notice Returns true if this contract implements the interface defined by `interfaceId` + * @param interfaceId_ the interface ID to check + * @return true if the passed interface ID is supported, otherwise false + */ + function supportsInterface(bytes4 interfaceId_) public view virtual override returns (bool) { + return + interfaceId_ == type(IERC721Metadata).interfaceId || + interfaceId_ == type(ISBT).interfaceId || + super.supportsInterface(interfaceId_); + } + /** * @notice The function to mint the token * @param to_ the receiver of the token @@ -148,7 +161,7 @@ abstract contract SBT is ISBT, Initializable { _balances[to_].add(tokenId_); _tokenOwners[tokenId_] = to_; - emit Minted(to_, tokenId_); + emit Transfer(address(0), to_, tokenId_); } /** @@ -166,7 +179,7 @@ abstract contract SBT is ISBT, Initializable { delete _tokenURIs[tokenId_]; - emit Burned(owner_, tokenId_); + emit Transfer(owner_, address(0), tokenId_); } /** diff --git a/package-lock.json b/package-lock.json index 8fd53ad6..4005cdac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@solarity/solidity-lib", - "version": "2.6.0", + "version": "2.6.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@solarity/solidity-lib", - "version": "2.6.0", + "version": "2.6.1", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 92e80f13..d332037b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@solarity/solidity-lib", - "version": "2.6.1", + "version": "2.6.2", "license": "MIT", "author": "Distributed Lab", "description": "Solidity Library by Distributed Lab", diff --git a/test/token/SBT.test.ts b/test/token/SBT.test.ts index 036002f1..1b924f1e 100644 --- a/test/token/SBT.test.ts +++ b/test/token/SBT.test.ts @@ -47,7 +47,7 @@ describe("SBT", () => { describe("mint()", () => { it("should correctly mint", async () => { - await sbt.mint(FIRST.address, 1337); + const tx = await sbt.mint(FIRST.address, 1337); expect(await sbt.tokenExists(1337)).to.be.true; @@ -58,6 +58,8 @@ describe("SBT", () => { expect(await sbt.tokensOf(FIRST.address)).to.deep.equal([1337n]); expect(await sbt.tokenURI(1337)).to.equal(""); + + expect(tx).to.emit(sbt, "Transfer").withArgs(ZERO_ADDR, FIRST.address, 1337); }); it("should not mint to null address", async () => { @@ -73,7 +75,7 @@ describe("SBT", () => { describe("burn()", () => { it("should correctly burn", async () => { - await sbt.mint(FIRST.address, 1337); + const tx = await sbt.mint(FIRST.address, 1337); await sbt.burn(1337); @@ -83,6 +85,8 @@ describe("SBT", () => { expect(await sbt.ownerOf(0)).to.equal(ZERO_ADDR); expect(await sbt.tokensOf(FIRST.address)).to.deep.equal([]); + + expect(tx).to.emit(sbt, "Transfer").withArgs(FIRST.address, ZERO_ADDR, 1337); }); it("should not burn SBT that doesn't exist", async () => { @@ -129,4 +133,20 @@ describe("SBT", () => { expect(await sbt.tokenURI(1337)).to.equal("test"); }); }); + + describe("supportsInterface()", () => { + it("should return correct values", async () => { + const IERC721MetadaInterfaceID = "0x5b5e139f"; + const ISBTInterfaceID = "0xddd872b5"; + const IERC165InterfaceID = "0x01ffc9a7"; + + expect(await sbt.supportsInterface(IERC721MetadaInterfaceID)).to.be.eq(true); + expect(await sbt.supportsInterface(ISBTInterfaceID)).to.be.eq(true); + expect(await sbt.supportsInterface(IERC165InterfaceID)).to.be.eq(true); + + const randomInterfaceID = "0xaaa1234d"; + + expect(await sbt.supportsInterface(randomInterfaceID)).to.be.eq(false); + }); + }); });