From ee160e603ffdc36f20b96594b73a5731b97fe188 Mon Sep 17 00:00:00 2001 From: george-openformat Date: Thu, 16 May 2024 17:55:48 +0100 Subject: [PATCH 1/6] feat: add mintBadge --- src/facet/RewardsFacet.sol | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/facet/RewardsFacet.sol b/src/facet/RewardsFacet.sol index 96296c2..d486a3b 100644 --- a/src/facet/RewardsFacet.sol +++ b/src/facet/RewardsFacet.sol @@ -14,6 +14,13 @@ interface NFT { function ownerOf(uint256 tokenId) external returns (address); } +interface Badge { + function mintTo(address to) external; + function batchMintTo(address to, uint256 quantity) external; + function transferFrom(address from, address to, uint256 tokenId) external; + function ownerOf(uint256 tokenId) external returns (address); +} + interface Token { function mintTo(address to, uint256 amount) external; function transferFrom(address holder, address receipient, uint256 amount) external; @@ -79,6 +86,22 @@ contract RewardsFacet is Multicall, SafeOwnable { emit BadgeMinted(_token, _quantity, _to, _id, _activityType, _uri); } + function mintBadge( + address _token, + address _to, + uint256 _quantity, + bytes32 _id, + bytes32 _activityType, + string calldata _uri + ) public { + if (!_canMint(_token)) { + revert RewardsFacet_NotAuthorized(); + } + + Badge(_token).batchMintTo(_to, _quantity); + emit BadgeMinted(_token, _quantity, _to, _id, _activityType, _uri); + } + function transferERC721( address _token, address _to, From 86f325550cf3615e9ea57b185d2c21130d9b8501 Mon Sep 17 00:00:00 2001 From: george-openformat Date: Thu, 16 May 2024 17:56:24 +0100 Subject: [PATCH 2/6] test: setup, mintBadge --- test/integration/facet/RewardsFacet.t.sol | 62 ++++++++++++++++++++++- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/test/integration/facet/RewardsFacet.t.sol b/test/integration/facet/RewardsFacet.t.sol index 467e6c9..60f22be 100644 --- a/test/integration/facet/RewardsFacet.t.sol +++ b/test/integration/facet/RewardsFacet.t.sol @@ -18,7 +18,10 @@ import {RegistryMock} from "src/registry/RegistryMock.sol"; import {AppFactory} from "src/factories/App.sol"; import {Globals} from "src/globals/Globals.sol"; -import {ERC20Base, ADMIN_ROLE, MINTER_ROLE} from "src/tokens/ERC20/ERC20Base.sol"; +import {ERC721Badge} from "src/tokens/ERC721/ERC721Badge.sol"; +import {IERC721Factory} from "@extensions/ERC721Factory/IERC721Factory.sol"; +import {ERC721FactoryFacet} from "src/facet/ERC721FactoryFacet.sol"; +import {ERC20Base} from "src/tokens/ERC20/ERC20Base.sol"; import {IERC20Factory} from "@extensions/ERC20Factory/IERC20Factory.sol"; import {ERC20FactoryFacet} from "src/facet/ERC20FactoryFacet.sol"; import {RewardsFacet} from "src/facet/RewardsFacet.sol"; @@ -42,13 +45,15 @@ abstract contract Helpers { * @dev dummy contract to test platform fee is not paid when called from a contract * must first grant MINTER_ROLE to this contract */ - contract MinterDummy { function mintTo(address _erc20, address _account, uint256 _amount) public { ERC20Base(_erc20).mintTo(_account, _amount); } } +bytes32 constant ADMIN_ROLE = bytes32(uint256(0)); +bytes32 constant MINTER_ROLE = bytes32(uint256(1)); + contract Setup is Test, Helpers { address creator; address other; @@ -63,10 +68,18 @@ contract Setup is Test, Helpers { SettingsFacet settingsFacet; RewardsFacet rewardsFacet; + ERC721Badge erc721Implementation; + bytes32 erc721ImplementationId; + ERC721FactoryFacet erc721FactoryFacet; + ERC20Base erc20Implementation; bytes32 erc20ImplementationId; ERC20FactoryFacet erc20FactoryFacet; + // ipfs uri taken from https://docs.ipfs.tech/how-to/best-practices-for-nft-data/#types-of-ipfs-links-and-when-to-use-them + string baseURI = "ipfs://bafybeibnsoufr2renqzsh347nrx54wcubt5lgkeivez63xvivplfwhtpym/"; + uint16 tenPercentBPS = 1000; + function setUp() public { // assign addresses creator = address(0x10); @@ -81,6 +94,10 @@ contract Setup is Test, Helpers { appImplementation = new Proxy(true); appFactory = new AppFactory(address(appImplementation), address(registry), address(globals)); + erc721Implementation = new ERC721Badge(false); + erc721ImplementationId = bytes32("Badge"); + erc721FactoryFacet = new ERC721FactoryFacet(); + erc20Implementation = new ERC20Base(); erc20ImplementationId = bytes32("Base"); erc20FactoryFacet = new ERC20FactoryFacet(); @@ -91,6 +108,7 @@ contract Setup is Test, Helpers { // setup globals globals.setPlatformFee(0, 0, socialConscious); + globals.setERC721Implementation(erc721ImplementationId, address(erc721Implementation)); globals.setERC20Implementation(erc20ImplementationId, address(erc20Implementation)); settingsFacet = new SettingsFacet(); @@ -115,6 +133,7 @@ contract Setup is Test, Helpers { selectors[2] = rewardsFacet.mintERC721.selector; selectors[3] = rewardsFacet.transferERC721.selector; selectors[4] = rewardsFacet.multicall.selector; + selectors[0] = rewardsFacet.mintBadge.selector; registry.diamondCut( prepareSingleFacetCut(address(rewardsFacet), IDiamondWritableInternal.FacetCutAction.ADD, selectors), @@ -123,6 +142,22 @@ contract Setup is Test, Helpers { ); } + { + // add erc721FactoryFacet to registry + bytes4[] memory selectors = new bytes4[](4); + selectors[0] = erc721FactoryFacet.createERC721.selector; + selectors[1] = erc721FactoryFacet.createERC721WithTokenURI.selector; + selectors[2] = erc721FactoryFacet.getERC721FactoryImplementation.selector; + selectors[3] = erc721FactoryFacet.calculateERC721FactoryDeploymentAddress.selector; + registry.diamondCut( + prepareSingleFacetCut( + address(erc721FactoryFacet), IDiamondWritableInternal.FacetCutAction.ADD, selectors + ), + address(0), + "" + ); + } + { // add erc20FactoryFacet to registry bytes4[] memory selectors = new bytes4[](3); @@ -147,6 +182,29 @@ contract Setup is Test, Helpers { function _afterSetup() internal virtual {} } +contract RewardFacet__integration_mintBadge is Setup { + address badgeContractAddress; + + function _afterSetup() internal override { + vm.startPrank(creator); + badgeContractAddress = ERC721FactoryFacet(address(app)).createERC721WithTokenURI( + "Name", "Symbol", "tokenURI", creator, uint16(tenPercentBPS), bytes32("Badge") + ); + + // TODO: can this be done on initialisation to reduce transactions needed + ERC721Badge(badgeContractAddress).grantRole(MINTER_ROLE, address(app)); + + vm.stopPrank(); + } + + function test_rewards_badge() public { + vm.prank(creator); + RewardsFacet(address(app)).mintBadge(badgeContractAddress, creator, 1, "action id?", "mission?", "random data"); + + assertEq(ERC721Badge(badgeContractAddress).balanceOf(creator), 1); + } +} + contract ERC20Base_Setup is Setup { ERC20Base base; MinterDummy minter; From fc6d6791bfe01c9bcb7cb23f3981af044c2eee40 Mon Sep 17 00:00:00 2001 From: george-openformat Date: Mon, 20 May 2024 11:50:22 +0100 Subject: [PATCH 3/6] feat: update mintBadge, badgeMinted event + add batchMintBadge, ERC721Minted event --- src/facet/RewardsFacet.sol | 64 +++++++++++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 12 deletions(-) diff --git a/src/facet/RewardsFacet.sol b/src/facet/RewardsFacet.sol index d486a3b..6beacfa 100644 --- a/src/facet/RewardsFacet.sol +++ b/src/facet/RewardsFacet.sol @@ -35,7 +35,10 @@ bytes32 constant MINTER_ROLE = bytes32(uint256(1)); contract RewardsFacet is Multicall, SafeOwnable { event TokenMinted(address token, address to, uint256 amount, bytes32 id, bytes32 activityType, string uri); event TokenTransferred(address token, address to, uint256 amount, bytes32 id, bytes32 activityType, string uri); - event BadgeMinted(address token, uint256 quantity, address to, bytes32 id, bytes32 activityType, string uri); + event ERC721Minted(address token, uint256 quantity, address to, bytes32 id, bytes32 activityType, string uri); + event BadgeMinted( + address token, uint256 quantity, address to, bytes32 activityId, bytes32 activityType, bytes data + ); event BadgeTransferred(address token, address to, uint256 tokenId, bytes32 id, bytes32 activityType, string uri); error RewardsFacet_NotAuthorized(); @@ -69,27 +72,65 @@ contract RewardsFacet is Multicall, SafeOwnable { emit TokenTransferred(_token, _to, _amount, _id, _activityType, _uri); } - function mintERC721( - address _token, + /** + * @notice Mints a number of badges to an address and broadcasts activity metadata + * @dev The sender must have a role of admin or minter on the badge contract. + * The app being called must have a minter role on the badge contract. + * The activity metadata is emitted as an event for indexing. + * @param _badgeContract The address of the ERC721 contract that represents all badges of the same type + * @param _to The address of the recipient of the badges + * @param _quantity The amount of badges to mint + * @param _activityId The id associated with this activity for example "beat the boss" or "collected 100 berries" + * @param _activityType The type of activity e.g "mission" or "action" + * @param _data Any other data that will be useful + */ + function batchMintBadge( + address _badgeContract, address _to, uint256 _quantity, - string calldata _baseURI, - bytes32 _id, + bytes32 _activityId, bytes32 _activityType, - string calldata _uri + bytes calldata _data ) public { - if (!_canMint(_token)) { + if (!_canMint(_badgeContract)) { revert RewardsFacet_NotAuthorized(); } - NFT(_token).batchMintTo(_to, _quantity, _baseURI); - emit BadgeMinted(_token, _quantity, _to, _id, _activityType, _uri); + Badge(_badgeContract).batchMintTo(_to, _quantity); + emit BadgeMinted(_badgeContract, _quantity, _to, _activityId, _activityType, _data); } + /** + * @notice Mints one badge to an address and broadcasts activity metadata. + * @dev The sender must have a role of admin or minter on the badge contract. + * The app being called must have a minter role on the badge contract. + * The activity metadata is emitted as an event for indexing. + * @param _badgeContract The address of the ERC721 contract that represents all badges of the same type + * @param _to The address of the recipient of the badge + * @param _activityId The id associated with this activity for example "beat the boss" or "collected 100 berries" + * @param _activityType The type of activity for example "mission" or "action" + * @param _data Any other data that will be useful + */ function mintBadge( + address _badgeContract, + address _to, + bytes32 _activityId, + bytes32 _activityType, + bytes calldata _data + ) public { + if (!_canMint(_badgeContract)) { + revert RewardsFacet_NotAuthorized(); + } + + Badge(_badgeContract).mintTo(_to); + emit BadgeMinted(_badgeContract, 1, _to, _activityId, _activityType, _data); + } + + function mintERC721( address _token, address _to, uint256 _quantity, + string calldata _baseURI, bytes32 _id, bytes32 _activityType, string calldata _uri @@ -97,9 +138,8 @@ contract RewardsFacet is Multicall, SafeOwnable { if (!_canMint(_token)) { revert RewardsFacet_NotAuthorized(); } - - Badge(_token).batchMintTo(_to, _quantity); - emit BadgeMinted(_token, _quantity, _to, _id, _activityType, _uri); + NFT(_token).batchMintTo(_to, _quantity, _baseURI); + emit ERC721Minted(_token, _quantity, _to, _id, _activityType, _uri); } function transferERC721( From a099149668bd3aea3aa20d39055b17e22e3ef733 Mon Sep 17 00:00:00 2001 From: george-openformat Date: Mon, 20 May 2024 11:51:28 +0100 Subject: [PATCH 4/6] test: mintBadge, batchMintBadge, multicall --- test/integration/facet/RewardsFacet.t.sol | 104 +++++++++++++++++++--- 1 file changed, 92 insertions(+), 12 deletions(-) diff --git a/test/integration/facet/RewardsFacet.t.sol b/test/integration/facet/RewardsFacet.t.sol index 60f22be..00792ae 100644 --- a/test/integration/facet/RewardsFacet.t.sol +++ b/test/integration/facet/RewardsFacet.t.sol @@ -76,10 +76,21 @@ contract Setup is Test, Helpers { bytes32 erc20ImplementationId; ERC20FactoryFacet erc20FactoryFacet; + bytes32 badgeImplementationId = bytes32("Badge"); + address badgeContract; + string name = "Name"; + string symbol = "Symbol"; + bytes32 activityId = "collected a berry"; + bytes32 activityType = "action"; // ipfs uri taken from https://docs.ipfs.tech/how-to/best-practices-for-nft-data/#types-of-ipfs-links-and-when-to-use-them string baseURI = "ipfs://bafybeibnsoufr2renqzsh347nrx54wcubt5lgkeivez63xvivplfwhtpym/"; uint16 tenPercentBPS = 1000; + event ERC721Minted(address token, uint256 quantity, address to, bytes32 id, bytes32 activityType, string uri); + event BadgeMinted( + address token, uint256 quantity, address to, bytes32 activityId, bytes32 activityType, bytes data + ); + function setUp() public { // assign addresses creator = address(0x10); @@ -127,13 +138,14 @@ contract Setup is Test, Helpers { rewardsFacet = new RewardsFacet(); { // add RewardsFacet to registry - bytes4[] memory selectors = new bytes4[](5); + bytes4[] memory selectors = new bytes4[](7); selectors[0] = rewardsFacet.mintERC20.selector; selectors[1] = rewardsFacet.transferERC20.selector; selectors[2] = rewardsFacet.mintERC721.selector; selectors[3] = rewardsFacet.transferERC721.selector; selectors[4] = rewardsFacet.multicall.selector; - selectors[0] = rewardsFacet.mintBadge.selector; + selectors[5] = rewardsFacet.mintBadge.selector; + selectors[6] = rewardsFacet.batchMintBadge.selector; registry.diamondCut( prepareSingleFacetCut(address(rewardsFacet), IDiamondWritableInternal.FacetCutAction.ADD, selectors), @@ -173,6 +185,12 @@ contract Setup is Test, Helpers { ); } + // use app to create badge contract + vm.prank(creator); + badgeContract = ERC721FactoryFacet(address(app)).createERC721WithTokenURI( + name, symbol, baseURI, creator, uint16(tenPercentBPS), badgeImplementationId + ); + _afterSetup(); } @@ -183,25 +201,87 @@ contract Setup is Test, Helpers { } contract RewardFacet__integration_mintBadge is Setup { - address badgeContractAddress; + function test_rewards_badge() public { + vm.prank(creator); + RewardsFacet(address(app)).mintBadge(badgeContract, other, activityId, activityType, ""); - function _afterSetup() internal override { - vm.startPrank(creator); - badgeContractAddress = ERC721FactoryFacet(address(app)).createERC721WithTokenURI( - "Name", "Symbol", "tokenURI", creator, uint16(tenPercentBPS), bytes32("Badge") + assertEq(ERC721Badge(badgeContract).balanceOf(other), 1); + } + + function test_emits_badge_minted_event() public { + vm.expectEmit(true, true, true, true); + emit BadgeMinted(badgeContract, 1, other, activityId, activityType, ""); + + vm.prank(creator); + RewardsFacet(address(app)).mintBadge(badgeContract, other, activityId, activityType, ""); + } + + function test_can_encode_string_in_data_emitted_in_badge_minted_event() public { + vm.expectEmit(true, true, true, true); + emit BadgeMinted(badgeContract, 1, other, activityId, activityType, abi.encode("testing 123")); + + vm.prank(creator); + RewardsFacet(address(app)).mintBadge(badgeContract, other, activityId, activityType, abi.encode("testing 123")); + } +} + +contract RewardFacet__integration_batchMintBadge is Setup { + function test_rewards_multiple_badges() public { + vm.prank(creator); + RewardsFacet(address(app)).batchMintBadge(badgeContract, other, 10, activityId, activityType, ""); + + assertEq(ERC721Badge(badgeContract).balanceOf(other), 10); + } + + function test_emits_badge_minted_event() public { + vm.expectEmit(true, true, true, true); + emit BadgeMinted(badgeContract, 10, other, activityId, activityType, ""); + + vm.prank(creator); + RewardsFacet(address(app)).batchMintBadge(badgeContract, other, 10, activityId, activityType, ""); + } + + function test_can_encode_string_in_data_emitted_in_badge_minted_event() public { + vm.expectEmit(true, true, true, true); + emit BadgeMinted(badgeContract, 10, other, activityId, activityType, abi.encode("testing 123")); + + vm.prank(creator); + RewardsFacet(address(app)).batchMintBadge( + badgeContract, other, 10, activityId, activityType, abi.encode("testing 123") ); + } + + function test_reverts_when_sender_not_authorised() public { + vm.expectRevert(RewardsFacet.RewardsFacet_NotAuthorized.selector); - // TODO: can this be done on initialisation to reduce transactions needed - ERC721Badge(badgeContractAddress).grantRole(MINTER_ROLE, address(app)); + vm.prank(other); + RewardsFacet(address(app)).batchMintBadge(badgeContract, other, 10, activityId, activityType, ""); + } + + function test_reverts_when_app_not_granted_minter_role() public { + vm.startPrank(creator); + ERC721Badge(badgeContract).revokeRole(MINTER_ROLE, address(app)); + vm.expectRevert(); + RewardsFacet(address(app)).batchMintBadge(badgeContract, other, 10, activityId, activityType, ""); vm.stopPrank(); } +} + +contract RewardFacet__integration_multicall is Setup { + function test_can_multicall_minting_badges() public { + bytes[] memory calls = new bytes[](2); + calls[0] = + abi.encodeCall(RewardsFacet(address(app)).mintBadge, (badgeContract, other, activityId, activityType, "")); + calls[1] = abi.encodeCall( + RewardsFacet(address(app)).batchMintBadge, (badgeContract, creator, 10, activityId, activityType, "") + ); - function test_rewards_badge() public { vm.prank(creator); - RewardsFacet(address(app)).mintBadge(badgeContractAddress, creator, 1, "action id?", "mission?", "random data"); + RewardsFacet(address(app)).multicall(calls); - assertEq(ERC721Badge(badgeContractAddress).balanceOf(creator), 1); + assertEq(ERC721Badge(badgeContract).balanceOf(other), 1); + assertEq(ERC721Badge(badgeContract).balanceOf(creator), 10); } } From 3a76b9054e470c6d2715153f412faa2bc25bb366 Mon Sep 17 00:00:00 2001 From: george-openformat Date: Mon, 20 May 2024 12:08:22 +0100 Subject: [PATCH 5/6] feat: add scripts for rewards facet --- Makefile | 21 +++++++++ scripts/facet/RewardsFacet.s.sol | 80 +++++++++++++++++++++++++++++++- 2 files changed, 99 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 9052409..d62a117 100644 --- a/Makefile +++ b/Makefile @@ -107,6 +107,20 @@ ERC721Badge.setBaseURI:; forge script \ --rpc-url $(rpc) --broadcast $(verbose) $(legacy) $(slow) \ $(word 1, $(args)) $(word 2, $(args)) +# pass the badge contract address as an argument +# example: make RewardFacet.mintBadge args="0xaf4c80136581212185f37c5e8809120d8fbf6224" +RewardsFacet.mintBadge:; forge script \ + scripts/facet/RewardsFacet.s.sol:mintBadge \ + --sig "run(address)" \ + --rpc-url $(rpc) --broadcast $(verbose) $(legacy) $(slow) $(args) + +# pass the badge contract address as an argument +# example: make RewardFacet.batchMintBadge args="0xaf4c80136581212185f37c5e8809120d8fbf6224" +RewardsFacet.batchMintBadge:; forge script \ + scripts/facet/RewardsFacet.s.sol:batchMintBadge \ + --sig "run(address)" \ + --rpc-url $(rpc) --broadcast $(verbose) $(legacy) $(slow) $(args) + # Run all update scripts update:; make \ update-ERC721FactoryFacet \ @@ -117,6 +131,13 @@ update:; make \ update-ERC721FactoryFacet:; forge script scripts/facet/ERC721FactoryFacet.s.sol:Update --rpc-url $(rpc) --broadcast $(verbose) $(legacy) $(slow) update-ERC20FactoryFacet:; forge script scripts/facet/ERC20FactoryFacet.s.sol:Update --rpc-url $(rpc) --broadcast $(verbose) $(legacy) $(slow) +# Add badge minting functionality +# Date 20.05.24 +# updates ERC721RewardFacet to update mintERC721 function and add mintBadge and batchMintBadge functions +# deploys and registers RewardsFacet contract +# PR #126 https://github.com/open-format/contracts/pull/126 +update-RewardsFacet:; forge script scripts/facet/RewardsFacet.s.sol:Update_Add_badgeMintingFunctionality --rpc-url $(rpc) --broadcast $(verbose) $(legacy) $(slow) + # Add ERC721Badge contract # Date 14.05.24 # updates ERC721FactoryFacet to change the createERC721 function to include a baseTokenURI paramerter diff --git a/scripts/facet/RewardsFacet.s.sol b/scripts/facet/RewardsFacet.s.sol index af54dfd..a52b331 100644 --- a/scripts/facet/RewardsFacet.s.sol +++ b/scripts/facet/RewardsFacet.s.sol @@ -22,12 +22,14 @@ contract Deploy is Script, Utils { RewardsFacet rewardsFacet = new RewardsFacet(); // construct array of function selectors - bytes4[] memory selectors = new bytes4[](5); + bytes4[] memory selectors = new bytes4[](7); selectors[0] = rewardsFacet.mintERC20.selector; selectors[1] = rewardsFacet.transferERC20.selector; selectors[2] = rewardsFacet.mintERC721.selector; selectors[3] = rewardsFacet.transferERC721.selector; selectors[4] = rewardsFacet.multicall.selector; + selectors[5] = rewardsFacet.mintBadge.selector; + selectors[6] = rewardsFacet.batchMintBadge.selector; // construct and ADD facet cut IDiamondWritableInternal.FacetCut[] memory cuts = new IDiamondWritableInternal.FacetCut[](1); @@ -53,12 +55,14 @@ contract Update is Script, Utils { RewardsFacet rewardsFacet = new RewardsFacet(); // construct array of function selectors - bytes4[] memory selectors = new bytes4[](5); + bytes4[] memory selectors = new bytes4[](7); selectors[0] = rewardsFacet.mintERC20.selector; selectors[1] = rewardsFacet.transferERC20.selector; selectors[2] = rewardsFacet.mintERC721.selector; selectors[3] = rewardsFacet.transferERC721.selector; selectors[4] = rewardsFacet.multicall.selector; + selectors[5] = rewardsFacet.mintBadge.selector; + selectors[6] = rewardsFacet.batchMintBadge.selector; // construct and ADD facet cut IDiamondWritableInternal.FacetCut[] memory cuts = new IDiamondWritableInternal.FacetCut[](1); @@ -74,3 +78,75 @@ contract Update is Script, Utils { exportContractDeployment(CONTRACT_NAME, address(rewardsFacet), block.number); } } + +contract mintBadge is Script, Utils { + function run(address _badgeContract) public { + uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); + address deployerAddress = vm.addr(deployerPrivateKey); + address appId = vm.envAddress("APP_ID"); + vm.startBroadcast(deployerPrivateKey); + + RewardsFacet rewardsFacet = RewardsFacet(appId); + + rewardsFacet.mintBadge(_badgeContract, deployerAddress, "collected berries", "action", ""); + + vm.stopBroadcast(); + } +} + +contract batchMintBadge is Script, Utils { + function run(address _badgeContract) public { + uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); + address deployerAddress = vm.addr(deployerPrivateKey); + address appId = vm.envAddress("APP_ID"); + vm.startBroadcast(deployerPrivateKey); + + RewardsFacet rewardsFacet = RewardsFacet(appId); + + rewardsFacet.batchMintBadge(_badgeContract, deployerAddress, 10, "collected berries", "action", ""); + + vm.stopBroadcast(); + } +} + +/** + * @dev use this script to updated deployments made previous to PR #126 https://github.com/open-format/contracts/pull/126/files + */ +contract Update_Add_badgeMintingFunctionality is Script, Utils { + function run() external { + uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); + vm.startBroadcast(deployerPrivateKey); + + // deploy + RewardsFacet rewardsFacet = new RewardsFacet(); + + // construct array of function selectors to replace + bytes4[] memory replaceSelectors = new bytes4[](5); + replaceSelectors[0] = rewardsFacet.mintERC20.selector; + replaceSelectors[1] = rewardsFacet.transferERC20.selector; + replaceSelectors[2] = rewardsFacet.mintERC721.selector; + replaceSelectors[3] = rewardsFacet.transferERC721.selector; + replaceSelectors[4] = rewardsFacet.multicall.selector; + + // construct array of function selectors to add + bytes4[] memory addSelectors = new bytes4[](2); + addSelectors[0] = rewardsFacet.mintBadge.selector; + addSelectors[1] = rewardsFacet.batchMintBadge.selector; + + // construct and ADD facet cut + IDiamondWritableInternal.FacetCut[] memory cuts = new IDiamondWritableInternal.FacetCut[](2); + cuts[0] = IDiamondWritableInternal.FacetCut( + address(rewardsFacet), IDiamondWritableInternal.FacetCutAction.REPLACE, replaceSelectors + ); + cuts[1] = IDiamondWritableInternal.FacetCut( + address(rewardsFacet), IDiamondWritableInternal.FacetCutAction.ADD, addSelectors + ); + + // add to registry + RegistryMock(payable(getContractDeploymentAddress("Registry"))).diamondCut(cuts, address(0), ""); + + vm.stopBroadcast(); + + exportContractDeployment(CONTRACT_NAME, address(rewardsFacet), block.number); + } +} From b232e314081ebe73387a83b39143cbcacd972f13 Mon Sep 17 00:00:00 2001 From: george-openformat Date: Mon, 20 May 2024 12:21:43 +0100 Subject: [PATCH 6/6] docs(changeset): update rewards facet to mint badges --- .changeset/warm-ladybugs-share.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/warm-ladybugs-share.md diff --git a/.changeset/warm-ladybugs-share.md b/.changeset/warm-ladybugs-share.md new file mode 100644 index 0000000..b49385d --- /dev/null +++ b/.changeset/warm-ladybugs-share.md @@ -0,0 +1,5 @@ +--- +"@openformat/contracts": minor +--- + +update rewards facet to mint badges