diff --git a/contracts/NftRentalMarketplace.sol b/contracts/NftRentalMarketplace.sol index 64d3d23..39b379a 100644 --- a/contracts/NftRentalMarketplace.sol +++ b/contracts/NftRentalMarketplace.sol @@ -310,4 +310,13 @@ contract NftRentalMarketplace is Initializable, OwnableUpgradeable, PausableUpgr function unpause() external onlyOwner { _unpause(); } + + /** + * @notice Sets the address of the OriumMarketplaceRoyalties contract. + * @dev Only owner can call this function. + * @param _oriumMarketplaceRoyalties The address of the OriumMarketplaceRoyalties contract. + */ + function setOriumMarketplaceRoyalties(address _oriumMarketplaceRoyalties) external onlyOwner { + oriumMarketplaceRoyalties = _oriumMarketplaceRoyalties; + } } diff --git a/package-lock.json b/package-lock.json index 070f38e..f56782d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,6 @@ "@openzeppelin/contracts-upgradeable": "^4.8.0-rc.1", "@openzeppelin/hardhat-upgrades": "^3.0.5", "@peculiar/asn1-ecc": "^2.3.8", - "@peculiar/asn1-schema": "^2.3.8", "defender-admin-client": "^1.37.0", "dotenv": "^16.0.3", "hardhat": "^2.22.2", diff --git a/scripts/nft-rental-marketplace/05-set-royalties.ts b/scripts/nft-rental-marketplace/05-set-royalties.ts new file mode 100644 index 0000000..7035024 --- /dev/null +++ b/scripts/nft-rental-marketplace/05-set-royalties.ts @@ -0,0 +1,22 @@ +import { print, colors } from '../../utils/misc' +import { callContractFunction } from '../../utils/write-contract' +import addresses, { Network } from '../../addresses' +import { network } from 'hardhat' + +const NETWORK = network.name as Network +const CONTRACT_NAME = 'NftRentalMarketplace' +const CONTRACT_FUNCTION = 'setOriumMarketplaceRoyalties' +const FUNCTION_PARAMS = [addresses[NETWORK].OriumMarketplaceRoyalties.address] + +async function main() { + await callContractFunction(CONTRACT_NAME, CONTRACT_FUNCTION, FUNCTION_PARAMS) +} + +main() + .then(() => { + print(colors.bigSuccess, 'All done!') + }) + .catch(error => { + console.error(error) + process.exitCode = 1 + }) diff --git a/scripts/nft-rental-marketplace/06-upgrade.ts b/scripts/nft-rental-marketplace/06-upgrade.ts new file mode 100644 index 0000000..1ef8255 --- /dev/null +++ b/scripts/nft-rental-marketplace/06-upgrade.ts @@ -0,0 +1,17 @@ +import { print, colors } from '../../utils/misc' +import { upgradeProxy } from '../../utils/upgrade-proxy' + +const CONTRACT_NAME = 'NftRentalMarketplace' + +async function main() { + await upgradeProxy(CONTRACT_NAME) +} + +main() + .then(() => { + print(colors.bigSuccess, 'All done!') + }) + .catch(error => { + console.error(error) + process.exitCode = 1 + }) diff --git a/scripts/nft-rental-marketplace/07-approve-nft.ts b/scripts/nft-rental-marketplace/07-approve-nft.ts new file mode 100644 index 0000000..70e9b0d --- /dev/null +++ b/scripts/nft-rental-marketplace/07-approve-nft.ts @@ -0,0 +1,23 @@ +import { print, colors } from '../../utils/misc' +import { callContractFunction } from '../../utils/write-contract' +import addresses, { Network } from '../../addresses' +import { network } from 'hardhat' + +const NETWORK = network.name as Network +const CONTRACT_NAME = 'MockERC721' +const CONTRACT_FUNCTION = 'setApprovalForAll' +const FUNCTION_PARAMS = [addresses[NETWORK].NftRentalMarketplace.address, true] +const CUSTOM_CONTRACT_ADDRESS = '0xcB13945Ca8104f813992e4315F8fFeFE64ac49cA' + +async function main() { + await callContractFunction(CONTRACT_NAME, CONTRACT_FUNCTION, FUNCTION_PARAMS, { CUSTOM_CONTRACT_ADDRESS }) +} + +main() + .then(() => { + print(colors.bigSuccess, 'All done!') + }) + .catch(error => { + console.error(error) + process.exitCode = 1 + }) diff --git a/utils/upgrade-proxy.ts b/utils/upgrade-proxy.ts new file mode 100644 index 0000000..e43bde8 --- /dev/null +++ b/utils/upgrade-proxy.ts @@ -0,0 +1,94 @@ +import hre, { ethers, network, upgrades } from 'hardhat' +import { print, confirmOrDie, colors } from './misc' +import addresses, { Network } from '../addresses' +import { updateJsonFile } from './json' +import { kmsDeployer, kmsProvider } from './deployer' + +const NETWORK = network.name as Network + +/** + * @notice Upgrade an proxy contract + * @dev The contract must existis in a solidity file in the contracts folder with the same name + * @param PROXY_CONTRACT_NAME The name of the contract + * @param LIBRARIES_CONTRACT_NAME The name of the libraries + * @param CUSTOM_FEE_DATA The custom fee data + */ +export async function upgradeProxy( + PROXY_CONTRACT_NAME: keyof (typeof addresses)[Network], + LIBRARIES_CONTRACT_NAME?: string[], + CUSTOM_FEE_DATA?: { maxFeePerGas: bigint; maxPriorityFeePerGas: bigint }, +) { + if (CUSTOM_FEE_DATA !== undefined) { + const FEE_DATA: any = CUSTOM_FEE_DATA + kmsProvider.getFeeData = async () => FEE_DATA + } + const deployerAddress = await kmsDeployer.getAddress() + const libraries: { [key: string]: string } = {} + + await confirmOrDie( + `Upgrading ${PROXY_CONTRACT_NAME} contract on: ${NETWORK} network with ${deployerAddress}. Continue?`, + ) + + if (LIBRARIES_CONTRACT_NAME !== undefined) { + print(colors.highlight, 'Deploying libraries...') + + for (const LIBRARY_CONTRACT_NAME of LIBRARIES_CONTRACT_NAME) { + const LibraryFactory = await ethers.getContractFactory(LIBRARY_CONTRACT_NAME, kmsDeployer) + const library = await LibraryFactory.deploy() + await library.waitForDeployment() + libraries[LIBRARY_CONTRACT_NAME] = await library.getAddress() + } + + print(colors.success, 'Libraries deployed!') + } + + print(colors.highlight, 'Upgrading proxy contract...') + const ContractFactory = await ethers.getContractFactory(PROXY_CONTRACT_NAME, { + libraries, + signer: kmsDeployer, + }) + const contract = await upgrades.upgradeProxy(addresses[NETWORK][PROXY_CONTRACT_NAME].address, ContractFactory, { + unsafeAllowLinkedLibraries: true, + }) + await contract.waitForDeployment() + print(colors.success, `${PROXY_CONTRACT_NAME} upgraded to: ${contract.address}`) + + print(colors.highlight, 'Updating config files...') + const deploymentInfo: any = { + [PROXY_CONTRACT_NAME]: { + ...addresses[NETWORK][PROXY_CONTRACT_NAME], + implementation: await upgrades.erc1967.getImplementationAddress(await contract.getAddress()), + }, + } + + if (LIBRARIES_CONTRACT_NAME) { + deploymentInfo[PROXY_CONTRACT_NAME].libraries = libraries + } + + console.log(deploymentInfo) + updateJsonFile(`addresses/${NETWORK}/index.json`, deploymentInfo) + print(colors.success, 'Config files updated!') + + if (LIBRARIES_CONTRACT_NAME) { + print(colors.highlight, 'Verifying libraries on block explorer...') + for (const LIBRARY_CONTRACT_NAME of LIBRARIES_CONTRACT_NAME) { + try { + print(colors.highlight, `Verifying library ${LIBRARY_CONTRACT_NAME}...`) + await hre.run('verify:verify', { + address: libraries[LIBRARY_CONTRACT_NAME], + constructorArguments: [], + }) + print(colors.success, `${LIBRARY_CONTRACT_NAME} verified!`) + } catch (e) { + print(colors.error, `Error verifying library ${LIBRARY_CONTRACT_NAME}: ${e}`) + } + } + } + + print(colors.highlight, 'Verifying contract on block explorer...') + await hre.run('verify:verify', { + address: await contract.getAddress(), + constructorArguments: [], + }) + print(colors.success, `${PROXY_CONTRACT_NAME} verified!`) +} diff --git a/utils/write-contract.ts b/utils/write-contract.ts index e449208..66c3e43 100644 --- a/utils/write-contract.ts +++ b/utils/write-contract.ts @@ -12,15 +12,19 @@ const NETWORK = network.name as Network * @param CONTRACT_NAME The name of the contract * @param FUNCTION_NAME The function to call * @param FUNCTION_ARGUMENTS The arguments to pass to the function - * @param CUSTOM_FEE_DATA The custom fee data (optional) + * @param OPTIONS The custom fee data, signer or contract file name */ export async function callContractFunction( - CONTRACT_NAME: keyof (typeof config)[Network], + CONTRACT_NAME: keyof (typeof config)[Network] | string, FUNCTION_NAME: string, FUNCTION_ARGUMENTS: any, - CUSTOM_FEE_DATA?: { maxFeePerGas: bigint; maxPriorityFeePerGas: bigint }, - CUSTOM_SIGNER?: Signer, + OPTIONS: { + CUSTOM_FEE_DATA?: { maxFeePerGas: bigint; maxPriorityFeePerGas: bigint } + CUSTOM_SIGNER?: Signer + CUSTOM_CONTRACT_ADDRESS?: string + }, ) { + const { CUSTOM_FEE_DATA, CUSTOM_SIGNER, CUSTOM_CONTRACT_ADDRESS } = OPTIONS const signer = CUSTOM_SIGNER || (await ethers.getSigners())[0] console.log('CONTRACT_NAME', CONTRACT_NAME) await confirmOrDie( @@ -32,7 +36,11 @@ export async function callContractFunction( } print(colors.warn, `Arguments:`) console.log(FUNCTION_ARGUMENTS) - const contract = await ethers.getContractAt(CONTRACT_NAME, config[NETWORK][CONTRACT_NAME].address, signer) + const contract = await ethers.getContractAt( + CONTRACT_NAME, + CUSTOM_CONTRACT_ADDRESS ?? config[NETWORK][CONTRACT_NAME as keyof (typeof config)[Network]].address, + signer, + ) print(colors.highlight, `Sending Transaction...`) const response = await contract[FUNCTION_NAME](...FUNCTION_ARGUMENTS) print(colors.highlight, `Waiting for transaction to be mined...`)