Skip to content

Commit

Permalink
add more test
Browse files Browse the repository at this point in the history
  • Loading branch information
andresaiello committed Aug 23, 2024
1 parent 805f146 commit 7905bed
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ contract InstantRewards is Ownable, Pausable, ReentrancyGuard {
address public signerAddress;

event Claimed(address indexed to, bytes32 indexed taskId, uint256 amount);
event Withdrawn(address indexed wallet, uint256 amount);

error InvalidSigner();
error SignatureExpired();
Expand Down Expand Up @@ -91,6 +92,15 @@ contract InstantRewards is Ownable, Pausable, ReentrancyGuard {
if (wallet == address(0)) revert InvalidAddress();
if (amount > address(this).balance) revert TransferFailed();
payable(wallet).transfer(amount);
emit Withdrawn(wallet, amount);
}

Check warning

Code scanning / Slither

Reentrancy vulnerabilities Warning

Reentrancy in InstantRewards.withdraw(address,uint256):
External calls:
- address(wallet).transfer(amount)
Event emitted after the call(s):
- Withdrawn(wallet,amount)

function pause() external onlyOwner {
_pause();
}

function unpause() external onlyOwner {
_unpause();
}

receive() external payable {}
Expand Down
124 changes: 111 additions & 13 deletions packages/zevm-app-contracts/test/instant-rewards/instant-rewards.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers";
import { expect } from "chai";
import { utils } from "ethers";
import { BigNumber, utils } from "ethers";
import { ethers } from "hardhat";

import { InstantRewards } from "../../typechain-types";
Expand All @@ -15,6 +15,27 @@ describe("Instant Rewards Contract test", () => {

const encodeTaskId = (taskId: string) => utils.keccak256(utils.defaultAbiCoder.encode(["string"], [taskId]));

const getClaimDataSigned = async (
signer: SignerWithAddress,
amount: BigNumber,
sigExpiration: number,
taskId: string,
to: string
) => {
const claimData: ClaimData = {
amount,
sigExpiration,
taskId,
to,
};

const signature = await getSignature(signer, claimData);
return {
...claimData,
signature,
};
};

beforeEach(async () => {
[owner, signer, user, ...addrs] = await ethers.getSigners();
const instantRewardsFactory = await ethers.getContractFactory("InstantRewards");
Expand All @@ -28,7 +49,7 @@ describe("Instant Rewards Contract test", () => {
const currentBlock = await ethers.provider.getBlock("latest");
const sigExpiration = currentBlock.timestamp + 1000;
const amount = utils.parseEther("1");
const taskId = encodeTaskId("1/1/1");
const taskId = encodeTaskId("WALLET/TASK/EPOC");
const to = owner.address;

// transfer some funds to the contract
Expand All @@ -37,23 +58,80 @@ describe("Instant Rewards Contract test", () => {
value: amount,
});

const claimData: ClaimData = {
amount,
sigExpiration,
taskId,
to,
};
const claimDataSigned = await getClaimDataSigned(signer, amount, sigExpiration, taskId, to);

const signature = await getSignature(signer, claimData);
const claimDataSigned = {
...claimData,
signature,
};
const tx = instantRewards.claim(claimDataSigned);
await expect(tx).to.emit(instantRewards, "Claimed").withArgs(owner.address, taskId, amount);
});

it("Should claim if pause and unpause", async () => {
const currentBlock = await ethers.provider.getBlock("latest");
const sigExpiration = currentBlock.timestamp + 1000;
const amount = utils.parseEther("1");
const taskId = encodeTaskId("WALLET/TASK/EPOC");
const to = owner.address;

await instantRewards.pause();
await instantRewards.unpause();

// transfer some funds to the contract
await owner.sendTransaction({
to: instantRewards.address,
value: amount,
});

const claimDataSigned = await getClaimDataSigned(signer, amount, sigExpiration, taskId, to);

const tx = instantRewards.claim(claimDataSigned);
await expect(tx).to.emit(instantRewards, "Claimed").withArgs(owner.address, taskId, amount);
});

it("Should revert if try to claim on behalf of somebody else", async () => {
const currentBlock = await ethers.provider.getBlock("latest");
const sigExpiration = currentBlock.timestamp + 1000;
const amount = utils.parseEther("1");
const taskId = encodeTaskId("WALLET/TASK/EPOC");
const to = user.address;

const claimDataSigned = await getClaimDataSigned(signer, amount, sigExpiration, taskId, to);

const tx = instantRewards.claim(claimDataSigned);
await expect(tx).to.revertedWith("InvalidSigner");
});

it("Should revert if try to claim with an expired signature", async () => {
const currentBlock = await ethers.provider.getBlock("latest");
const sigExpiration = currentBlock.timestamp - 1000;
const amount = utils.parseEther("1");
const taskId = encodeTaskId("WALLET/TASK/EPOC");
const to = owner.address;

const claimDataSigned = await getClaimDataSigned(signer, amount, sigExpiration, taskId, to);

const tx = instantRewards.claim(claimDataSigned);
await expect(tx).to.revertedWith("SignatureExpired");
});

it("Should revert if try to claim when contract it's paused", async () => {
const currentBlock = await ethers.provider.getBlock("latest");
const sigExpiration = currentBlock.timestamp + 1000;
const amount = utils.parseEther("1");
const taskId = encodeTaskId("WALLET/TASK/EPOC");
const to = owner.address;

await instantRewards.pause();

const claimDataSigned = await getClaimDataSigned(signer, amount, sigExpiration, taskId, to);

const tx = instantRewards.claim(claimDataSigned);
await expect(tx).to.revertedWith("Pausable: paused");
});

it("Should revert if not owner try to pause", async () => {
const tx = instantRewards.connect(user).pause();
await expect(tx).to.revertedWith("Ownable: caller is not the owner");
});

it("Should transfer ownership", async () => {
{
const ownerAddr = await instantRewards.owner();
Expand All @@ -65,4 +143,24 @@ describe("Instant Rewards Contract test", () => {
expect(ownerAddr).to.be.eq(user.address);
}
});

it("Should withdraw by owner", async () => {
const amount = utils.parseEther("2");
const amountToWithdraw = utils.parseEther("1");
// transfer some funds to the contract
await owner.sendTransaction({
to: instantRewards.address,
value: amount,
});

const userBalanceBefore = await ethers.provider.getBalance(user.address);

const tx = instantRewards.withdraw(user.address, amountToWithdraw);
await expect(tx).to.emit(instantRewards, "Withdrawn").withArgs(user.address, amountToWithdraw);

const balanceOfContract = await ethers.provider.getBalance(instantRewards.address);
expect(balanceOfContract).to.be.eq(amount.sub(amountToWithdraw));
const balanceOfUser = await ethers.provider.getBalance(user.address);
expect(balanceOfUser).to.be.eq(userBalanceBefore.add(amountToWithdraw));
});
});

0 comments on commit 7905bed

Please sign in to comment.