diff --git a/packages/zevm-app-contracts/contracts/instant-rewards/InstantRewardsFactory.sol b/packages/zevm-app-contracts/contracts/instant-rewards/InstantRewardsFactory.sol index 3a0560f..1a64f77 100644 --- a/packages/zevm-app-contracts/contracts/instant-rewards/InstantRewardsFactory.sol +++ b/packages/zevm-app-contracts/contracts/instant-rewards/InstantRewardsFactory.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.20; -import "@openzeppelin/contracts/access/Ownable2Step.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; import "./InstantRewardsV2.sol"; -contract InstantRewardsFactory is Ownable2Step { +contract InstantRewardsFactory is Ownable { bool public allowPublicCreation = false; error AccessDenied(); @@ -13,7 +13,7 @@ contract InstantRewardsFactory is Ownable2Step { error StartTimeInPast(); error EndTimeBeforeStart(); - event InstantRewardsCreated(address indexed instantRewards, address indexed owner); + event InstantRewardsCreated(address indexed instantRewards, address indexed owner, string indexed name); constructor(address owner) Ownable() { transferOwnership(owner); @@ -27,7 +27,10 @@ contract InstantRewardsFactory is Ownable2Step { address signerAddress, uint256 start, uint256 end, - string memory name + string memory name, + string memory promoUrl, + string memory avatarUrl, + string memory description ) external returns (address) { if (signerAddress == address(0)) revert InvalidSignerAddress(); if (bytes(name).length == 0) revert EmptyName(); @@ -37,9 +40,18 @@ contract InstantRewardsFactory is Ownable2Step { bool isOwner = owner() == msg.sender; if (!allowPublicCreation && !isOwner) revert AccessDenied(); - InstantRewardsV2 instantRewards = new InstantRewardsV2(signerAddress, owner(), start, end, name); + InstantRewardsV2 instantRewards = new InstantRewardsV2( + signerAddress, + owner(), + start, + end, + name, + promoUrl, + avatarUrl, + description + ); instantRewards.transferOwnership(owner()); - emit InstantRewardsCreated(address(instantRewards), owner()); + emit InstantRewardsCreated(address(instantRewards), owner(), name); return address(instantRewards); } } diff --git a/packages/zevm-app-contracts/contracts/instant-rewards/InstantRewardsV2.sol b/packages/zevm-app-contracts/contracts/instant-rewards/InstantRewardsV2.sol index 145eeeb..80df1aa 100644 --- a/packages/zevm-app-contracts/contracts/instant-rewards/InstantRewardsV2.sol +++ b/packages/zevm-app-contracts/contracts/instant-rewards/InstantRewardsV2.sol @@ -8,6 +8,9 @@ contract InstantRewardsV2 is InstantRewards { uint256 public start; uint256 public end; + string public promoUrl; + string public avatarUrl; + string public description; event TimeframeUpdated(uint256 start, uint256 end); @@ -20,13 +23,19 @@ contract InstantRewardsV2 is InstantRewards { address owner, uint256 start_, uint256 end_, - string memory name_ + string memory name_, + string memory promoUrl_, + string memory avatarUrl_, + string memory description_ ) InstantRewards(signerAddress_, owner) { if (signerAddress_ == address(0)) revert InvalidAddress(); if (start_ > end_) revert InvalidTimeframe(); start = start_; end = end_; name = name_; + promoUrl = promoUrl_; + avatarUrl = avatarUrl_; + description = description_; } function isActive() public view returns (bool) { @@ -48,7 +57,6 @@ contract InstantRewardsV2 is InstantRewards { } function withdraw(address wallet, uint256 amount) public override onlyOwner { - if (isActive()) revert InstantRewardStillActive(); super.withdraw(wallet, amount); } } diff --git a/packages/zevm-app-contracts/data/addresses.json b/packages/zevm-app-contracts/data/addresses.json index acfec2f..29ef608 100644 --- a/packages/zevm-app-contracts/data/addresses.json +++ b/packages/zevm-app-contracts/data/addresses.json @@ -12,7 +12,8 @@ "ProofOfLiveness": "0x981EB6fD19717Faf293Fba0cBD05C6Ac97b8C808", "TimelockController": "0x44139C2150c11c25f517B8a8F974b59C82aEe709", "ZetaXPGov": "0x854032d484aE21acC34F36324E55A8080F21Af12", - "invitationManagerV2": "0xb80f6360194Dd6B47B80bd8730b3dBb05a39e723" + "invitationManagerV2": "0xb80f6360194Dd6B47B80bd8730b3dBb05a39e723", + "InstantRewardsFactory": "0x02F054A5BeeB2653d1c2403cBe9B262356fdD5E4" }, "zeta_mainnet": { "disperse": "0x23ce409Ea60c3d75827d04D9db3d52F3af62e44d", @@ -22,7 +23,7 @@ "invitationManager": "0x3649C03C472B698213926543456E9c21081e529d", "withdrawERC20": "0xa349B9367cc54b47CAb8D09A95836AE8b4D1d84E", "ZetaXP": "0x9A4e8bB5FFD8088ecF1DdE823e97Be8080BD38cb", - "InstantRewards": "0x018412ec1D5bBb864eAe0A4BECaa683052890238", + "InstantRewards": "0xfD5dcBf68c81274B48593Cb4b0322e965741392b", "ProofOfLiveness": "0x327c9837B183e69C522a30E6f91A42c86e057432" } } diff --git a/packages/zevm-app-contracts/hardhat.config.ts b/packages/zevm-app-contracts/hardhat.config.ts index 6a7320b..05120c4 100644 --- a/packages/zevm-app-contracts/hardhat.config.ts +++ b/packages/zevm-app-contracts/hardhat.config.ts @@ -40,8 +40,8 @@ const config: HardhatUserConfig = { chainId: 7001, network: "zeta_testnet", urls: { - apiURL: "https://zetachain-athens-3.blockscout.com/api", - browserURL: "https://zetachain-athens-3.blockscout.com", + apiURL: "https://zetachain-testnet.blockscout.com/api", + browserURL: "https://zetachain-testnet.blockscout.com", }, }, ], @@ -52,6 +52,13 @@ const config: HardhatUserConfig = { }, networks: { ...getHardhatConfigNetworks(), + zeta_mainnet: { + accounts: PRIVATE_KEYS, + chainId: 7000, + gas: "auto", + gasMultiplier: 3, + url: `https://zetachain-evm.blockpi.network/v1/rpc/public`, + }, }, solidity: { compilers: [ diff --git a/packages/zevm-app-contracts/scripts/instant-rewards/deploy-v2.ts b/packages/zevm-app-contracts/scripts/instant-rewards/deploy-v2.ts index 67319f3..240977c 100644 --- a/packages/zevm-app-contracts/scripts/instant-rewards/deploy-v2.ts +++ b/packages/zevm-app-contracts/scripts/instant-rewards/deploy-v2.ts @@ -7,7 +7,7 @@ import { verifyContract } from "../explorer.helpers"; const networkName = network.name; -const owner = "0x1d24d94520B94B26351f6573de5ef9731c48531A"; +const owner = "0xD7E8bD37db625a4856E056D2617C9d140dB99182"; const deployInstantRewards = async () => { if (!isProtocolNetworkName(networkName)) throw new Error("Invalid network name"); @@ -21,7 +21,7 @@ const deployInstantRewards = async () => { console.log("InstantRewards deployed to:", InstantRewards.address); - saveAddress("InstantRewards", InstantRewards.address, networkName); + saveAddress("InstantRewardsFactory", InstantRewards.address, networkName); await verifyContract(InstantRewards.address, [owner]); }; diff --git a/packages/zevm-app-contracts/test/instant-rewards/instant-rewards-v2-compatibility.ts b/packages/zevm-app-contracts/test/instant-rewards/instant-rewards-v2-compatibility.ts index 7ac1ff1..87dfb31 100644 --- a/packages/zevm-app-contracts/test/instant-rewards/instant-rewards-v2-compatibility.ts +++ b/packages/zevm-app-contracts/test/instant-rewards/instant-rewards-v2-compatibility.ts @@ -48,7 +48,16 @@ describe("Instant Rewards V2 Contract Compatibility test", () => { const start = (await ethers.provider.getBlock("latest")).timestamp + 1; const end = start + 1000; - instantRewards = await instantRewardsFactory.deploy(signer.address, owner.address, start, end, "Instant Rewards"); + instantRewards = await instantRewardsFactory.deploy( + signer.address, + owner.address, + start, + end, + "Instant Rewards", + "http://img.com", + "http://avatar.com", + "Description" + ); await instantRewards.deployed(); }); @@ -322,7 +331,7 @@ describe("Instant Rewards V2 Contract Compatibility test", () => { expect(balanceOfUser).to.be.eq(userBalanceBefore.add(amountToWithdraw)); }); - it("Should fail if try to withdraw an active IR", async () => { + it("Should be able to withdraw an active IR", async () => { const amount = utils.parseEther("2"); const amountToWithdraw = utils.parseEther("1"); // transfer some funds to the contract @@ -331,7 +340,6 @@ describe("Instant Rewards V2 Contract Compatibility test", () => { value: amount, }); - const tx = instantRewards.withdraw(user.address, amountToWithdraw); - await expect(tx).to.revertedWith("InstantRewardStillActive"); + await instantRewards.withdraw(user.address, amountToWithdraw); }); }); diff --git a/packages/zevm-app-contracts/test/instant-rewards/instant-rewards-v2.ts b/packages/zevm-app-contracts/test/instant-rewards/instant-rewards-v2.ts index 41009c6..1395d82 100644 --- a/packages/zevm-app-contracts/test/instant-rewards/instant-rewards-v2.ts +++ b/packages/zevm-app-contracts/test/instant-rewards/instant-rewards-v2.ts @@ -17,7 +17,6 @@ describe("Instant Rewards Contract test", () => { const instantRewardsFactoryF = await ethers.getContractFactory("InstantRewardsFactory"); instantRewardsFactory = (await instantRewardsFactoryF.deploy(owner.address)) as InstantRewardsFactory; await instantRewardsFactory.deployed(); - await instantRewardsFactory.connect(owner).acceptOwnership(); }); it("Should deploy an IR instance", async () => { @@ -25,7 +24,9 @@ describe("Instant Rewards Contract test", () => { const start = currentBlock.timestamp + 1000; const end = start + 1000; const name = "Instant Rewards"; - const tx = instantRewardsFactory.connect(owner).createInstantRewards(signer.address, start, end, name); + const tx = instantRewardsFactory + .connect(owner) + .createInstantRewards(signer.address, start, end, name, "http://img.com", "http://avatar.com", "Description"); await expect(tx).to.emit(instantRewardsFactory, "InstantRewardsCreated"); const events = await instantRewardsFactory.queryFilter("InstantRewardsCreated"); @@ -47,7 +48,15 @@ describe("Instant Rewards Contract test", () => { const start = currentBlock.timestamp + 1000; const end = start + 1000; const name = "Instant Rewards"; - const tx = instantRewardsFactory.createInstantRewards(signer.address, start, end, name); + const tx = instantRewardsFactory.createInstantRewards( + signer.address, + start, + end, + name, + "http://img.com", + "http://avatar.com", + "Description" + ); await expect(tx).to.revertedWith("AccessDenied"); }); @@ -58,7 +67,15 @@ describe("Instant Rewards Contract test", () => { const start = currentBlock.timestamp + 1000; const end = start + 1000; const name = "Instant Rewards"; - const tx = instantRewardsFactory.createInstantRewards(signer.address, start, end, name); + const tx = instantRewardsFactory.createInstantRewards( + signer.address, + start, + end, + name, + "http://img.com", + "http://avatar.com", + "Description" + ); await expect(tx).to.emit(instantRewardsFactory, "InstantRewardsCreated"); }); });