From 9dac80677241f948c95f6260f8ac92275c3777af Mon Sep 17 00:00:00 2001 From: Yash Agrawal Date: Thu, 22 Feb 2024 11:57:14 +0530 Subject: [PATCH 1/4] feat: add SBTProxy --- contracts/SBTProxy.sol | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 contracts/SBTProxy.sol diff --git a/contracts/SBTProxy.sol b/contracts/SBTProxy.sol new file mode 100644 index 0000000..575ec0a --- /dev/null +++ b/contracts/SBTProxy.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MPL-2.0 +pragma solidity =0.8.9; + +import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; + +contract SBTProxy is TransparentUpgradeableProxy { + constructor( + address _logic, + address admin_, + bytes memory _data + ) TransparentUpgradeableProxy(_logic, admin_, _data) {} +} From 26701578a661340ae82ffc8a4b5f3280d91c47ad Mon Sep 17 00:00:00 2001 From: Yash Agrawal Date: Thu, 22 Feb 2024 12:14:13 +0530 Subject: [PATCH 2/4] feat: add metadataOf in sbt --- contracts/SBT.sol | 11 ++++++++++- contracts/interfaces/ISBT.sol | 7 +++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/contracts/SBT.sol b/contracts/SBT.sol index 9b3f774..b2e4168 100644 --- a/contracts/SBT.sol +++ b/contracts/SBT.sol @@ -106,6 +106,8 @@ contract SBT is ISBT, ERC721EnumerableUpgradeable { } function _tokenURI(uint256 tokenId) private view returns (string memory) { + require(tokenId < currentIndex(), "Token not found"); + ( string memory name, string memory description, @@ -113,7 +115,7 @@ contract SBT is ISBT, ERC721EnumerableUpgradeable { StringAttribute[] memory stringAttributes, NumberAttribute[] memory numberAttributes ) = abi.decode( - _sbtdata[tokenId], + metadataOf(tokenId), (string, string, string, StringAttribute[], NumberAttribute[]) ); @@ -230,6 +232,13 @@ contract SBT is ISBT, ERC721EnumerableUpgradeable { return super.totalSupply(); } + function metadataOf( + uint256 tokenId + ) public view override returns (bytes memory) { + require(tokenId < currentIndex(), "Token not found"); + return _sbtdata[tokenId]; + } + function owner() external view returns (address) { return ProxyAdmin(_proxyAdmin).owner(); } diff --git a/contracts/interfaces/ISBT.sol b/contracts/interfaces/ISBT.sol index fce4272..701e79e 100644 --- a/contracts/interfaces/ISBT.sol +++ b/contracts/interfaces/ISBT.sol @@ -111,4 +111,11 @@ interface ISBT { * @return uint256 current token id */ function currentIndex() external view returns (uint256); + + /* + * @dev get mapped metadata bytes of token id + * @param tokenId the token id of the NFT + * @return bytes The mapped metadata bytes + */ + function metadataOf(uint256 tokenId) external view returns (bytes memory); } From 1050a3b06432da45638c6ed34fa3e8876c990579 Mon Sep 17 00:00:00 2001 From: Yash Agrawal Date: Thu, 22 Feb 2024 12:25:44 +0530 Subject: [PATCH 3/4] feat: remove _proxyAdmin from SBT --- contracts/SBT.sol | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/contracts/SBT.sol b/contracts/SBT.sol index b2e4168..23315cb 100644 --- a/contracts/SBT.sol +++ b/contracts/SBT.sol @@ -3,7 +3,6 @@ pragma solidity =0.8.9; import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; import {Base64} from "@devprotocol/util-contracts/contracts/utils/Base64.sol"; -import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; import {ERC721EnumerableUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol"; import {ISBT} from "./interfaces/ISBT.sol"; @@ -12,8 +11,6 @@ contract SBT is ISBT, ERC721EnumerableUpgradeable { using Base64 for bytes; using Strings for uint256; - /// @dev Account with proxy adming rights. - address private _proxyAdmin; /// @dev EOA with rights to allow(add)/disallow(remove) minter. address private _minterUpdater; @@ -70,12 +67,6 @@ contract SBT is ISBT, ERC721EnumerableUpgradeable { } } - function setProxyAdmin(address proxyAdmin) external { - require(_proxyAdmin == address(0), "Already set"); - _proxyAdmin = proxyAdmin; - emit SetProxyAdmin(proxyAdmin); - } - function addMinter(address minter) external override onlyMinterUpdater { _minters[minter] = true; emit MinterAdded(minter); @@ -239,10 +230,6 @@ contract SBT is ISBT, ERC721EnumerableUpgradeable { return _sbtdata[tokenId]; } - function owner() external view returns (address) { - return ProxyAdmin(_proxyAdmin).owner(); - } - function tokensOfOwner( address tokenOwner ) external view override returns (uint256[] memory) { From 315ef9ccef06095072c5e5334481721619f15533 Mon Sep 17 00:00:00 2001 From: Yash Agrawal Date: Thu, 22 Feb 2024 12:35:52 +0530 Subject: [PATCH 4/4] feat: update test cases to account for removing proxyAdmin --- test/SBT.test.ts | 35 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/test/SBT.test.ts b/test/SBT.test.ts index e41061a..3f7baae 100644 --- a/test/SBT.test.ts +++ b/test/SBT.test.ts @@ -30,25 +30,6 @@ describe('SBT', () => { }) }) - describe('setProxyAdmin', () => { - it('The setProxyAdmin function should execute once', async () => { - const sbt = await init() - const signers = await getSigners() - await expect(sbt.setProxyAdmin(signers.proxyAdmin.address)) - .to.emit(sbt, 'SetProxyAdmin') - .withArgs(signers.proxyAdmin.address) - }) - - it('The setProxyAdmin function can only be executed once', async () => { - const sbt = await init() - const signers = await getSigners() - await sbt.setProxyAdmin(signers.proxyAdmin.address) - await expect( - sbt.setProxyAdmin(signers.proxyAdmin.address) - ).to.be.revertedWith('Already set') - }) - }) - describe('addMinter', () => { it('The addMinter function can be executed by minterUpdater', async () => { const sbt = await init() @@ -68,7 +49,11 @@ describe('SBT', () => { ) await expect( - sbt.connect(signers.proxyAdmin).addMinter(signers.minterC.address) + sbt.connect(signers.deployer).addMinter(signers.minterC.address) + ).to.revertedWith('Not minter updater') + + await expect( + sbt.connect(signers.userA).addMinter(signers.minterC.address) ).to.revertedWith('Not minter updater') }) }) @@ -92,7 +77,11 @@ describe('SBT', () => { ) await expect( - sbt.connect(signers.proxyAdmin).removeMinter(signers.minterA.address) + sbt.connect(signers.deployer).removeMinter(signers.minterA.address) + ).to.revertedWith('Not minter updater') + + await expect( + sbt.connect(signers.userA).removeMinter(signers.minterA.address) ).to.revertedWith('Not minter updater') }) }) @@ -134,7 +123,7 @@ describe('SBT', () => { ).to.be.revertedWith('Illegal access') await expect( - sbt.connect(signers.proxyAdmin).mint(signers.userA.address, metadata) + sbt.connect(signers.userB).mint(signers.userA.address, metadata) ).to.be.revertedWith('Illegal access') await expect( @@ -493,7 +482,7 @@ describe('SBT', () => { metadata = await getDummyEncodedMetadata(sbt, 'USERC') await expect( - sbt.connect(signers.proxyAdmin).setTokenURI(0, metadata) + sbt.connect(signers.userB).setTokenURI(0, metadata) ).to.be.revertedWith('Illegal access') metadata = await getDummyEncodedMetadata(sbt, 'USERD')