Skip to content

Commit

Permalink
Merge pull request #6 from gpylypchuk/development
Browse files Browse the repository at this point in the history
Make NftReward contract upgradeable
  • Loading branch information
0x4007 authored Feb 15, 2024
2 parents dd88115 + 3d402c3 commit 2ca9591
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 27 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@
[submodule "lib/openzeppelin-contracts"]
path = lib/openzeppelin-contracts
url = https://github.com/OpenZeppelin/openzeppelin-contracts
[submodule "lib/openzeppelin-contracts-upgradeable"]
path = lib/openzeppelin-contracts-upgradeable
url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable
1 change: 1 addition & 0 deletions lib/openzeppelin-contracts-upgradeable
4 changes: 2 additions & 2 deletions remappings.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/
ds-test/=lib/forge-std/lib/ds-test/src/
erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/
forge-std/=lib/forge-std/src/
openzeppelin-contracts/=lib/openzeppelin-contracts/
@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/
@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/
22 changes: 14 additions & 8 deletions script/Deploy001_NftReward.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@ pragma solidity ^0.8.13;

import {Script} from "forge-std/Script.sol";
import {NftReward} from "../src/NftReward.sol";
import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";

contract Deploy001_NftReward is Script {
NftReward nftReward;
function run() public returns(address) {
// deploy NftReward contract
address proxy = deployNftReward();
return proxy;
}

function run() public {
function deployNftReward() public returns(address) {
// read env variables
address minterAddress = vm.envAddress("MINTER_ADDRESS");
string memory nftTokenName = vm.envString("NFT_TOKEN_NAME");
Expand All @@ -19,15 +24,16 @@ contract Deploy001_NftReward is Script {
// start sending owner transactions
vm.startBroadcast(ownerPrivateKey);

// deploy NftReward
nftReward = new NftReward{salt: salt}(
nftTokenName, // token name
nftTokenSymbol, // token symbol
ownerAddress, // owner address
minterAddress // minter address (who signs off-chain mint requests)
// deploy NftReward contract
NftReward nftReward = new NftReward{salt: salt}();
ERC1967Proxy proxy = new ERC1967Proxy(address(nftReward),
abi.encodeWithSignature("initialize(string,string,address,address)",
nftTokenName, nftTokenSymbol, ownerAddress, minterAddress)
);

// stop sending owner transactions
vm.stopBroadcast();

return address(proxy);
}
}
41 changes: 31 additions & 10 deletions src/NftReward.sol
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Pausable.sol";
import "@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol";
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "@openzeppelin/contracts/utils/cryptography/EIP712.sol";

/**
* @title NFT reward contract
* @notice Allows NFT minter to sign off-chain mint requests for target users
* who can later claim NFTs by minter's signature
*/
contract NftReward is ERC721, Ownable, Pausable, EIP712 {
contract NftReward is Initializable, ERC721Upgradeable, OwnableUpgradeable, PausableUpgradeable, EIP712Upgradeable, UUPSUpgradeable {
/// @notice Base URI used for all of the tokens
string public baseUri;

Expand Down Expand Up @@ -49,22 +50,35 @@ contract NftReward is ERC721, Ownable, Pausable, EIP712 {
}

/**
* @notice Contract constructor
* @notice _disableInitializers in the constructor,
* this prevents initialization of the implementation contract itself,
* as extra protection to prevent an attacker from initializing it.
*/
constructor() {
_disableInitializers();
}

/**
* @notice Contract initializer (replaces constructor)
* @param _tokenName NFT token name
* @param _tokenSymbol NFT token symbol
* @param _initialOwner Initial owner name
* @param _minter Minter address
*/
constructor (
function initialize(
string memory _tokenName,
string memory _tokenSymbol,
address _initialOwner,
address _minter
)
ERC721(_tokenName, _tokenSymbol)
Ownable(_initialOwner)
EIP712("NftReward-Domain", "1")
public
initializer
{
__ERC721_init(_tokenName, _tokenSymbol);
__Ownable_init(_initialOwner);
__EIP712_init("NftReward-Domain", "1");
__UUPSUpgradeable_init();
__Pausable_init();
minter = _minter;
}

Expand Down Expand Up @@ -193,6 +207,13 @@ contract NftReward is ERC721, Ownable, Pausable, EIP712 {
_unpause();
}

/**
* @notice Upgrades contract to new implementation
* @param newImplementation New implementation address
*/

function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}

//====================
// Internal methods
//====================
Expand Down
22 changes: 16 additions & 6 deletions test/NftReward.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pragma solidity ^0.8.13;

import {Test, console} from "forge-std/Test.sol";
import {NftReward} from "../src/NftReward.sol";
import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";

contract NftRewardTest is Test {
NftReward nftReward;
Expand All @@ -14,14 +15,23 @@ contract NftRewardTest is Test {
address user2 = address(3);
address minter = vm.addr(minterPrivateKey);

bytes public data;

function setUp() public {
vm.prank(owner);
nftReward = new NftReward(
"NFT reward", // token name
"RWD", // token symbol
owner, // initial owner
minter // minter (off-chain signer)

data = abi.encodeWithSignature(
"initialize(string,string,address,address)",
"NFT reward",
"RWD",
owner,
minter
);

nftReward = new NftReward();
ERC1967Proxy proxy = new ERC1967Proxy(address(nftReward), data);

nftReward = NftReward(address(proxy));
}

//==================
Expand All @@ -47,7 +57,7 @@ contract NftRewardTest is Test {
// get mint request digest which should be signed
bytes32 digest = nftReward.getMintRequestDigest(mintRequest);

assertEq(digest, 0x2c680706f2350ed5622f229af6736cd20626f7b9b4569b2fd5abb7e086886dc3);
assertEq(digest, 0xf85127466b4ea4a97ec0c1b445b54622c8c3760b720bf9136b491d50f122b043);
}

function testGetTokenDataKeys_ReturnAllTokenDataKeys() public {
Expand Down

0 comments on commit 2ca9591

Please sign in to comment.