-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: adding basic NFTMultiplier implementation, deploy script and c…
…onfig with tests Changes to be committed:
- Loading branch information
1 parent
fffe13b
commit fc1221b
Showing
3 changed files
with
150 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.22; | ||
|
||
import {Script} from "forge-std/Script.sol"; | ||
import {NFTMultiplier} from "src/multipliers/NFTMultiplier.sol"; | ||
import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; | ||
import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; | ||
import {console} from "forge-std/console.sol"; | ||
|
||
contract DeployNFTMultiplier is Script { | ||
function run() external { | ||
uint256 deployerPrivateKey; | ||
address nftContractAddress; | ||
uint256 initialMultiplyingFactor; | ||
uint256 validUntilBlock; | ||
|
||
string memory configPath = "deploy_config.json"; | ||
string memory jsonData; | ||
// Try to read the JSON file, if it doesn't exist or can't be read, catch the error | ||
try vm.readFile(configPath) returns (string memory data) { | ||
jsonData = data; | ||
} catch { | ||
console.log("Config file not found or couldn't be read. Falling back to environment variables."); | ||
jsonData = ""; | ||
} | ||
|
||
if (bytes(jsonData).length > 0) { | ||
// Read from JSON if file exists | ||
deployerPrivateKey = vm.parseJsonUint(jsonData, ".deployerPrivateKey"); | ||
nftContractAddress = vm.parseJsonAddress(jsonData, ".nftContractAddress"); | ||
initialMultiplyingFactor = vm.parseJsonUint(jsonData, ".initialMultiplyingFactor"); | ||
validUntilBlock = vm.parseJsonUint(jsonData, ".validUntilBlock"); | ||
} else { | ||
// Fall back to environment variables | ||
deployerPrivateKey = vm.envUint("PRIVATE_KEY"); | ||
nftContractAddress = vm.envAddress("NFT_CONTRACT_ADDRESS"); | ||
initialMultiplyingFactor = vm.envUint("INITIAL_MULTIPLYING_FACTOR"); | ||
validUntilBlock = vm.envUint("VALID_UNTIL_BLOCK"); | ||
} | ||
|
||
// Check if all required variables are set | ||
require(deployerPrivateKey != 0, "Deployer private key not set"); | ||
require(nftContractAddress != address(0), "NFT contract address not set"); | ||
require(initialMultiplyingFactor != 0, "Initial multiplying factor not set"); | ||
require(validUntilBlock != 0, "Valid until block not set"); | ||
|
||
vm.startBroadcast(deployerPrivateKey); | ||
|
||
NFTMultiplier implementation = new NFTMultiplier(); | ||
|
||
bytes memory initData = abi.encodeWithSelector( | ||
NFTMultiplier.initialize.selector, IERC721(nftContractAddress), initialMultiplyingFactor, validUntilBlock | ||
); | ||
|
||
TransparentUpgradeableProxy proxy = | ||
new TransparentUpgradeableProxy(address(implementation), vm.addr(deployerPrivateKey), initData); | ||
|
||
NFTMultiplier nftMultiplier = NFTMultiplier(address(proxy)); | ||
|
||
vm.stopBroadcast(); | ||
|
||
console.log("NFTMultiplier deployed at:", address(nftMultiplier)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"deployerPrivateKey": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", | ||
"nftContractAddress": "0x1234567890123456789012345678901234567890", | ||
"initialMultiplyingFactor": 100, | ||
"validUntilBlock": 1000000 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.22; | ||
|
||
import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; | ||
import {INFTMultiplier} from "src/interfaces/multipliers/INFTMultiplier.sol"; | ||
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; | ||
import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; | ||
|
||
/// @title NFT Multiplier | ||
/// @notice Implementation of INFTMultiplier interface | ||
/// @dev Provides multiplying factors based on NFT ownership | ||
contract NFTMultiplier is INFTMultiplier, Initializable, OwnableUpgradeable { | ||
IERC721 public nftContract; | ||
uint256 public multiplyingFactor; | ||
uint256 public validUntilBlock; | ||
|
||
/// @custom:oz-upgrades-unsafe-allow constructor | ||
constructor() { | ||
_disableInitializers(); | ||
} | ||
|
||
/// @notice Initializer function to set the NFT contract address and initial multiplying factor | ||
/// @param _nftContract Address of the NFT contract | ||
/// @param _initialMultiplyingFactor Initial multiplying factor (in basis points, e.g., 15000 for 1.5x) | ||
/// @param _validUntilBlock Block number until which the multiplier is valid | ||
function initialize(IERC721 _nftContract, uint256 _initialMultiplyingFactor, uint256 _validUntilBlock) | ||
public | ||
initializer | ||
{ | ||
__Ownable_init(msg.sender); | ||
|
||
nftContract = _nftContract; | ||
multiplyingFactor = _initialMultiplyingFactor; | ||
validUntilBlock = _validUntilBlock; | ||
} | ||
|
||
/// @notice Get the address of the NFT contract | ||
/// @return The address of the NFT contract used for checking ownership | ||
function NFTAddress() external view override returns (IERC721) { | ||
return nftContract; | ||
} | ||
|
||
/// @notice Check if a user owns an NFT | ||
/// @param user The address of the user to check | ||
/// @return True if the user owns at least one NFT, false otherwise | ||
function hasNFT(address user) public view override returns (bool) { | ||
return nftContract.balanceOf(user) > 0; | ||
} | ||
|
||
/// @notice Get the multiplying factor for a given user | ||
/// @param user The address of the user | ||
/// @return The multiplying factor if the user owns an NFT, 0 otherwise | ||
function getMultiplyingFactor(address user) external view override returns (uint256) { | ||
return hasNFT(user) ? multiplyingFactor : 0; | ||
} | ||
|
||
/// @notice Get the block number until which the multiplier is valid | ||
/// @return The block number until which the multiplier is valid | ||
function validUntil(address /* user */ ) external view override returns (uint256) { | ||
return validUntilBlock; | ||
} | ||
|
||
/// @notice Update the multiplying factor | ||
/// @param _newMultiplyingFactor New multiplying factor (in basis points) | ||
function updateMultiplyingFactor(uint256 _newMultiplyingFactor) external onlyOwner { | ||
multiplyingFactor = _newMultiplyingFactor; | ||
} | ||
|
||
/// @notice Update the valid until block | ||
/// @param _newValidUntilBlock New block number until which the multiplier is valid | ||
function updateValidUntilBlock(uint256 _newValidUntilBlock) external onlyOwner { | ||
validUntilBlock = _newValidUntilBlock; | ||
} | ||
|
||
/// @notice Update the NFT contract address | ||
/// @param _newNFTContract New NFT contract address | ||
function updateNFTContract(IERC721 _newNFTContract) external onlyOwner { | ||
nftContract = _newNFTContract; | ||
} | ||
} |