Skip to content

Commit

Permalink
feat: 1 smart contract per activity (#195)
Browse files Browse the repository at this point in the history
* feat: 1 smart contract per activity

* add test

* remove unused code

* add validations

* deploy to testnet
  • Loading branch information
andresaiello authored Nov 14, 2024
1 parent 41c98cd commit 0f7b077
Show file tree
Hide file tree
Showing 7 changed files with 540 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ contract InstantRewards is Ownable2Step, Pausable, ReentrancyGuard, EIP712 {
if (block.timestamp > claimData.sigExpiration) revert SignatureExpired();
}

function claim(ClaimData memory claimData) external nonReentrant whenNotPaused {
function claim(ClaimData memory claimData) public virtual nonReentrant whenNotPaused {
claimData.to = msg.sender;
_verify(claimData);

Expand All @@ -72,7 +72,7 @@ contract InstantRewards is Ownable2Step, Pausable, ReentrancyGuard, EIP712 {
emit SignerUpdated(signerAddress_);
}

function withdraw(address wallet, uint256 amount) external onlyOwner {
function withdraw(address wallet, uint256 amount) public virtual onlyOwner {
if (wallet == address(0)) revert InvalidAddress();
if (amount > address(this).balance) revert TransferFailed();
(bool success, ) = wallet.call{value: amount}("");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/access/Ownable2Step.sol";
import "./InstantRewardsV2.sol";

contract InstantRewardsFactory is Ownable2Step {
bool public allowPublicCreation = false;

error AccessDenied();
error InvalidSignerAddress();
error EmptyName();
error StartTimeInPast();
error EndTimeBeforeStart();

event InstantRewardsCreated(address indexed instantRewards, address indexed owner);

constructor(address owner) Ownable() {
transferOwnership(owner);
}

function setAllowPublicCreation(bool allowPublicCreation_) external onlyOwner {
allowPublicCreation = allowPublicCreation_;
}

function createInstantRewards(
address signerAddress,
uint256 start,
uint256 end,
string memory name
) external returns (address) {
if (signerAddress == address(0)) revert InvalidSignerAddress();
if (bytes(name).length == 0) revert EmptyName();
if (start < block.timestamp) revert StartTimeInPast();
if (end <= start) revert EndTimeBeforeStart();

bool isOwner = owner() == msg.sender;
if (!allowPublicCreation && !isOwner) revert AccessDenied();

InstantRewardsV2 instantRewards = new InstantRewardsV2(signerAddress, owner(), start, end, name);
instantRewards.transferOwnership(owner());
emit InstantRewardsCreated(address(instantRewards), owner());
return address(instantRewards);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "./InstantRewards.sol";

contract InstantRewardsV2 is InstantRewards {
string public name;

uint256 public start;
uint256 public end;

event TimeframeUpdated(uint256 start, uint256 end);

error InvalidTimeframe();
error InstantRewardNotActive();
error InstantRewardStillActive();

constructor(
address signerAddress_,
address owner,
uint256 start_,
uint256 end_,
string memory name_
) InstantRewards(signerAddress_, owner) {
if (signerAddress_ == address(0)) revert InvalidAddress();
if (start_ > end_) revert InvalidTimeframe();
start = start_;
end = end_;
name = name_;
}

function isActive() public view returns (bool) {
return block.timestamp >= start && block.timestamp <= end;
}

function setTimeframe(uint256 start_, uint256 end_) external onlyOwner {
if (start_ > end_) revert InvalidTimeframe();
if (start_ < block.timestamp || end_ < block.timestamp) revert InvalidTimeframe();
if (isActive()) revert InstantRewardStillActive();
start = start_;
end = end_;
emit TimeframeUpdated(start_, end_);
}

function claim(ClaimData memory claimData) public override {
if (!isActive()) revert InstantRewardNotActive();
super.claim(claimData);
}

function withdraw(address wallet, uint256 amount) public override onlyOwner {
if (isActive()) revert InstantRewardStillActive();
super.withdraw(wallet, amount);
}
}
2 changes: 1 addition & 1 deletion packages/zevm-app-contracts/data/addresses.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"invitationManager": "0x3649C03C472B698213926543456E9c21081e529d",
"withdrawERC20": "0xa349B9367cc54b47CAb8D09A95836AE8b4D1d84E",
"ZetaXP": "0x5c25b6f4D2b7a550a80561d3Bf274C953aC8be7d",
"InstantRewards": "0x10DfEd4ba9b8F6a1c998E829FfC0325D533c80E3",
"InstantRewards": "0xd91164c9671C5A2ee1C95fa34A95C9141dA691D4",
"ProofOfLiveness": "0x981EB6fD19717Faf293Fba0cBD05C6Ac97b8C808",
"TimelockController": "0x44139C2150c11c25f517B8a8F974b59C82aEe709",
"ZetaXPGov": "0x854032d484aE21acC34F36324E55A8080F21Af12",
Expand Down
37 changes: 37 additions & 0 deletions packages/zevm-app-contracts/scripts/instant-rewards/deploy-v2.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { isProtocolNetworkName } from "@zetachain/protocol-contracts";
import { ethers, network } from "hardhat";

import { InstantRewardsFactory__factory } from "../../typechain-types";
import { saveAddress } from "../address.helpers";
import { verifyContract } from "../explorer.helpers";

const networkName = network.name;

const owner = "0x1d24d94520B94B26351f6573de5ef9731c48531A";

const deployInstantRewards = async () => {
if (!isProtocolNetworkName(networkName)) throw new Error("Invalid network name");

const InstantRewardsFactory = (await ethers.getContractFactory(
"InstantRewardsFactory"
)) as InstantRewardsFactory__factory;
const InstantRewards = await InstantRewardsFactory.deploy(owner);

await InstantRewards.deployed();

console.log("InstantRewards deployed to:", InstantRewards.address);

saveAddress("InstantRewards", InstantRewards.address, networkName);

await verifyContract(InstantRewards.address, [owner]);
};

const main = async () => {
if (!isProtocolNetworkName(networkName)) throw new Error("Invalid network name");
await deployInstantRewards();
};

main().catch((error) => {
console.error(error);
process.exit(1);
});
Loading

0 comments on commit 0f7b077

Please sign in to comment.