added cancelDeposit unit tests
This commit is contained in:
parent
606406f889
commit
1a4b4973d4
@ -1,4 +1,4 @@
|
|||||||
{
|
{
|
||||||
"_format": "hh-sol-dbg-1",
|
"_format": "hh-sol-dbg-1",
|
||||||
"buildInfo": "../../build-info/ce60783a904758b510bc61bc47947601.json"
|
"buildInfo": "../../build-info/ba59382ab04b2124c4bb550173fdda55.json"
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{
|
{
|
||||||
"_format": "hh-sol-dbg-1",
|
"_format": "hh-sol-dbg-1",
|
||||||
"buildInfo": "../../build-info/ce60783a904758b510bc61bc47947601.json"
|
"buildInfo": "../../build-info/351fea96dbbd5ddc7250e49d27b4151f.json"
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import {
|
|||||||
network,
|
network,
|
||||||
/* , tracer */
|
/* , tracer */
|
||||||
} from "hardhat";
|
} from "hardhat";
|
||||||
|
import keccak256 from "keccak256";
|
||||||
|
|
||||||
import { MockToken, P2PIX, Reputation } from "../src/types";
|
import { MockToken, P2PIX, Reputation } from "../src/types";
|
||||||
import { P2PixErrors } from "./utils/errors";
|
import { P2PixErrors } from "./utils/errors";
|
||||||
@ -35,7 +36,9 @@ describe("P2PIX", () => {
|
|||||||
|
|
||||||
let p2pix: P2PIX; // Contract instance
|
let p2pix: P2PIX; // Contract instance
|
||||||
let erc20: MockToken; // Token instance
|
let erc20: MockToken; // Token instance
|
||||||
let reputation: Reputation; // Reputation Interface instance;
|
let reputation: Reputation; // Reputation Interface instance
|
||||||
|
let merkleRoot: string; // MerkleRoot from seller's allowlist
|
||||||
|
let proof: string[]; // Owner's proof as whitelisted address
|
||||||
|
|
||||||
const fundAmount: BigNumber =
|
const fundAmount: BigNumber =
|
||||||
ethers.utils.parseEther("10000");
|
ethers.utils.parseEther("10000");
|
||||||
@ -51,9 +54,8 @@ describe("P2PIX", () => {
|
|||||||
await network.provider.send("hardhat_reset");
|
await network.provider.send("hardhat_reset");
|
||||||
});
|
});
|
||||||
beforeEach("Load deployment fixtures", async () => {
|
beforeEach("Load deployment fixtures", async () => {
|
||||||
({ erc20, p2pix, reputation } = await loadFixture(
|
({ erc20, p2pix, reputation, merkleRoot, proof } =
|
||||||
p2pixFixture,
|
await loadFixture(p2pixFixture));
|
||||||
));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("Init", async () => {
|
describe("Init", async () => {
|
||||||
@ -330,11 +332,18 @@ describe("P2PIX", () => {
|
|||||||
});
|
});
|
||||||
// edge case test
|
// edge case test
|
||||||
it("should create multiple deposits", async () => {
|
it("should create multiple deposits", async () => {
|
||||||
const ownerKey = await p2pix.callStatic._castAddrToKey(owner.address);
|
const ownerKey = await p2pix.callStatic._castAddrToKey(
|
||||||
const acc01Key = await p2pix.callStatic._castAddrToKey(acc01.address);
|
owner.address,
|
||||||
const acc02Key = await p2pix.callStatic._castAddrToKey(acc02.address);
|
);
|
||||||
const acc03Key = await p2pix.callStatic._castAddrToKey(acc03.address);
|
const acc01Key = await p2pix.callStatic._castAddrToKey(
|
||||||
|
acc01.address,
|
||||||
|
);
|
||||||
|
const acc02Key = await p2pix.callStatic._castAddrToKey(
|
||||||
|
acc02.address,
|
||||||
|
);
|
||||||
|
const acc03Key = await p2pix.callStatic._castAddrToKey(
|
||||||
|
acc03.address,
|
||||||
|
);
|
||||||
|
|
||||||
const pTarget = ethers.utils.keccak256(
|
const pTarget = ethers.utils.keccak256(
|
||||||
ethers.utils.toUtf8Bytes("_pixTarget"),
|
ethers.utils.toUtf8Bytes("_pixTarget"),
|
||||||
@ -346,7 +355,7 @@ describe("P2PIX", () => {
|
|||||||
ethers.utils.toUtf8Bytes("_pixTarget3"),
|
ethers.utils.toUtf8Bytes("_pixTarget3"),
|
||||||
);
|
);
|
||||||
// we mock the allowlist root here only to test storage update. In depth
|
// we mock the allowlist root here only to test storage update. In depth
|
||||||
// allowlist test coverage in both "Lock" and "Seller Allowlist Settings" unit tests.
|
// allowlist test coverage in both "Lock" and "Allowlist Settings" unit tests.
|
||||||
const root = ethers.utils.keccak256(
|
const root = ethers.utils.keccak256(
|
||||||
ethers.utils.toUtf8Bytes("root"),
|
ethers.utils.toUtf8Bytes("root"),
|
||||||
);
|
);
|
||||||
@ -384,15 +393,23 @@ describe("P2PIX", () => {
|
|||||||
.connect(acc03)
|
.connect(acc03)
|
||||||
.deposit(erc20.address, price4, pTarget, nullRoot);
|
.deposit(erc20.address, price4, pTarget, nullRoot);
|
||||||
|
|
||||||
const storage1: Deposit = await p2pix.mapDeposits(0);
|
const storage1: Deposit = await p2pix.mapDeposits(0);
|
||||||
const storage2: Deposit = await p2pix.mapDeposits(1);
|
const storage2: Deposit = await p2pix.mapDeposits(1);
|
||||||
const storage3: Deposit = await p2pix.mapDeposits(2);
|
const storage3: Deposit = await p2pix.mapDeposits(2);
|
||||||
const storage4: Deposit = await p2pix.mapDeposits(3);
|
const storage4: Deposit = await p2pix.mapDeposits(3);
|
||||||
|
|
||||||
const allowList1 = await p2pix.sellerAllowList(ownerKey);
|
const allowList1 = await p2pix.sellerAllowList(
|
||||||
const allowList2 = await p2pix.sellerAllowList(acc01Key);
|
ownerKey,
|
||||||
const allowList3 = await p2pix.sellerAllowList(acc02Key);
|
);
|
||||||
const allowList4 = await p2pix.sellerAllowList(acc03Key);
|
const allowList2 = await p2pix.sellerAllowList(
|
||||||
|
acc01Key,
|
||||||
|
);
|
||||||
|
const allowList3 = await p2pix.sellerAllowList(
|
||||||
|
acc02Key,
|
||||||
|
);
|
||||||
|
const allowList4 = await p2pix.sellerAllowList(
|
||||||
|
acc03Key,
|
||||||
|
);
|
||||||
|
|
||||||
expect(tx).to.be.ok;
|
expect(tx).to.be.ok;
|
||||||
expect(tx2).to.be.ok;
|
expect(tx2).to.be.ok;
|
||||||
@ -455,7 +472,7 @@ describe("P2PIX", () => {
|
|||||||
expect(storage3.token).to.eq(erc20.address);
|
expect(storage3.token).to.eq(erc20.address);
|
||||||
expect(storage3.valid).to.eq(true);
|
expect(storage3.valid).to.eq(true);
|
||||||
expect(allowList3).to.eq(root);
|
expect(allowList3).to.eq(root);
|
||||||
|
|
||||||
expect(storage4.remaining).to.eq(price4);
|
expect(storage4.remaining).to.eq(price4);
|
||||||
expect(storage4.pixTarget).to.eq(pTarget);
|
expect(storage4.pixTarget).to.eq(pTarget);
|
||||||
expect(storage4.seller).to.eq(acc03.address);
|
expect(storage4.seller).to.eq(acc03.address);
|
||||||
@ -465,20 +482,222 @@ describe("P2PIX", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe("Lock", async () => {
|
describe("Lock", async () => {
|
||||||
// it ("should revert if deposit is invalid")
|
it("should revert if deposit is invalid", async () => {
|
||||||
// it ("should revert if wished amount is greater than deposit's remaining amount")
|
await erc20.approve(p2pix.address, price);
|
||||||
// it ("should revert if a non expired lock has the same ID encoded")
|
await p2pix.deposit(
|
||||||
// it ("should revert if an invalid allowlist merkleproof is provided")
|
erc20.address,
|
||||||
// it ("should revert if msg.sender does not have enough credit in his spend limit")
|
price,
|
||||||
|
"pixTarget",
|
||||||
|
ethers.constants.HashZero,
|
||||||
|
);
|
||||||
|
await p2pix.cancelDeposit(0);
|
||||||
|
const fail = p2pix
|
||||||
|
.connect(acc03)
|
||||||
|
.lock(
|
||||||
|
0,
|
||||||
|
acc02.address,
|
||||||
|
acc03.address,
|
||||||
|
0,
|
||||||
|
price,
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
const fail2 = p2pix.lock(
|
||||||
|
2,
|
||||||
|
zero,
|
||||||
|
zero,
|
||||||
|
0,
|
||||||
|
price,
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
await expect(fail).to.be.revertedWithCustomError(
|
||||||
|
p2pix,
|
||||||
|
P2PixErrors.InvalidDeposit,
|
||||||
|
);
|
||||||
|
await expect(fail2).to.be.revertedWithCustomError(
|
||||||
|
p2pix,
|
||||||
|
P2PixErrors.InvalidDeposit,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it("should revert if wished amount is greater than deposit's remaining amount", async () => {
|
||||||
|
await erc20.approve(p2pix.address, price);
|
||||||
|
await p2pix.deposit(
|
||||||
|
erc20.address,
|
||||||
|
price,
|
||||||
|
"pixTarget",
|
||||||
|
ethers.constants.HashZero,
|
||||||
|
);
|
||||||
|
const fail = p2pix
|
||||||
|
.connect(acc03)
|
||||||
|
.lock(
|
||||||
|
0,
|
||||||
|
acc02.address,
|
||||||
|
acc03.address,
|
||||||
|
0,
|
||||||
|
price.mul(ethers.BigNumber.from(2)),
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
await expect(fail).to.be.revertedWithCustomError(
|
||||||
|
p2pix,
|
||||||
|
P2PixErrors.NotEnoughTokens,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it("should revert if a non expired lock has the same ID encoded", async () => {
|
||||||
|
await erc20.approve(p2pix.address, price);
|
||||||
|
await p2pix.deposit(
|
||||||
|
erc20.address,
|
||||||
|
price,
|
||||||
|
"pixTarget",
|
||||||
|
ethers.constants.HashZero,
|
||||||
|
);
|
||||||
|
await p2pix
|
||||||
|
.connect(acc03)
|
||||||
|
.lock(0, acc02.address, acc03.address, 0, 1, [], []);
|
||||||
|
const fail = p2pix
|
||||||
|
.connect(acc03)
|
||||||
|
.lock(0, acc02.address, acc03.address, 0, 1, [], []);
|
||||||
|
|
||||||
|
await expect(fail).to.be.revertedWithCustomError(
|
||||||
|
p2pix,
|
||||||
|
P2PixErrors.NotExpired,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it("should revert if an invalid allowlist merkleproof is provided", async () => {
|
||||||
|
await erc20.approve(p2pix.address, price);
|
||||||
|
await p2pix.deposit(
|
||||||
|
erc20.address,
|
||||||
|
price,
|
||||||
|
"pixTarget",
|
||||||
|
merkleRoot,
|
||||||
|
);
|
||||||
|
const fail = p2pix
|
||||||
|
.connect(acc02)
|
||||||
|
.lock(
|
||||||
|
0,
|
||||||
|
acc02.address,
|
||||||
|
acc03.address,
|
||||||
|
0,
|
||||||
|
1000,
|
||||||
|
[
|
||||||
|
ethers.utils.keccak256(
|
||||||
|
ethers.utils.toUtf8Bytes("wrong"),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
await expect(fail).to.be.revertedWithCustomError(
|
||||||
|
p2pix,
|
||||||
|
P2PixErrors.AddressDenied,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it ("should revert if msg.sender does not have enough credit in his spend limit", async () => {
|
||||||
|
await erc20.approve(p2pix.address, price);
|
||||||
|
await p2pix.deposit(
|
||||||
|
erc20.address,
|
||||||
|
price,
|
||||||
|
"pixTarget",
|
||||||
|
merkleRoot,
|
||||||
|
);
|
||||||
|
const fail = p2pix
|
||||||
|
.connect(acc02)
|
||||||
|
.lock(
|
||||||
|
0,
|
||||||
|
acc02.address,
|
||||||
|
acc03.address,
|
||||||
|
0,
|
||||||
|
price,
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
await expect(fail).to.be.revertedWithCustomError(
|
||||||
|
p2pix,
|
||||||
|
P2PixErrors.AmountNotAllowed,
|
||||||
|
);
|
||||||
|
});
|
||||||
// it ("should create a lock, update storage and emit events via the allowlist path")
|
// it ("should create a lock, update storage and emit events via the allowlist path")
|
||||||
// it ("should create a lock, update storage and emit events via the reputation path")
|
// it ("should create a lock, update storage and emit events via the reputation path")
|
||||||
// it ("should create multiple locks") - EDGE CASE TEST
|
// it ("should create multiple locks") - EDGE CASE TEST
|
||||||
// CHECK UNEXPIRE LOCK
|
|
||||||
});
|
});
|
||||||
describe("Cancel Deposit", async () => {
|
describe("Cancel Deposit", async () => {
|
||||||
// it("should revert if the msg.sender isn't the deposit's seller")
|
it("should revert if the msg.sender isn't the deposit's seller", async () => {
|
||||||
// it("should cancel deposit, update storage and emit events")
|
await erc20.approve(p2pix.address, price);
|
||||||
// it("should cancel multiple deposits")
|
await p2pix.deposit(
|
||||||
|
erc20.address,
|
||||||
|
price,
|
||||||
|
"pixTarget",
|
||||||
|
merkleRoot,
|
||||||
|
);
|
||||||
|
const fail = p2pix.connect(acc01).cancelDeposit(0);
|
||||||
|
await expect(fail).to.be.revertedWithCustomError(p2pix, P2PixErrors.OnlySeller);
|
||||||
|
});
|
||||||
|
it("should cancel deposit, update storage and emit events", async () => {
|
||||||
|
await erc20.approve(p2pix.address, price);
|
||||||
|
await p2pix.deposit(
|
||||||
|
erc20.address,
|
||||||
|
price,
|
||||||
|
"pixTarget",
|
||||||
|
merkleRoot,
|
||||||
|
);
|
||||||
|
const state1:Deposit = await p2pix.callStatic.mapDeposits(0);
|
||||||
|
const tx = await p2pix.cancelDeposit(0);
|
||||||
|
const state2:Deposit = await p2pix.callStatic.mapDeposits(0);
|
||||||
|
|
||||||
|
expect(tx).to.be.ok;
|
||||||
|
await expect(tx).to.emit(p2pix, "DepositClosed").withArgs(owner.address, 0);
|
||||||
|
expect(state1.valid).to.be.true;
|
||||||
|
expect(state2.valid).to.be.false;
|
||||||
|
});
|
||||||
|
it("should cancel multiple deposits", async () => {
|
||||||
|
await erc20.approve(p2pix.address, price);
|
||||||
|
await p2pix.deposit(
|
||||||
|
erc20.address,
|
||||||
|
price,
|
||||||
|
"pixTarget",
|
||||||
|
ethers.constants.HashZero,
|
||||||
|
);
|
||||||
|
await erc20.approve(p2pix.address, price);
|
||||||
|
await p2pix.deposit(
|
||||||
|
erc20.address,
|
||||||
|
price,
|
||||||
|
"pixTarget",
|
||||||
|
ethers.constants.HashZero,
|
||||||
|
);
|
||||||
|
await erc20.approve(p2pix.address, price);
|
||||||
|
await p2pix.deposit(
|
||||||
|
erc20.address,
|
||||||
|
price,
|
||||||
|
"pixTarget",
|
||||||
|
ethers.constants.HashZero,
|
||||||
|
);
|
||||||
|
const oldState1:Deposit = await p2pix.callStatic.mapDeposits(0);
|
||||||
|
const oldState2:Deposit = await p2pix.callStatic.mapDeposits(1);
|
||||||
|
const oldState3:Deposit = await p2pix.callStatic.mapDeposits(2);
|
||||||
|
const tx1 = await p2pix.cancelDeposit(0);
|
||||||
|
const tx2 = await p2pix.cancelDeposit(1);
|
||||||
|
const tx3 = await p2pix.cancelDeposit(2);
|
||||||
|
const newState1:Deposit = await p2pix.callStatic.mapDeposits(0);
|
||||||
|
const newState2:Deposit = await p2pix.callStatic.mapDeposits(1);
|
||||||
|
const newState3:Deposit = await p2pix.callStatic.mapDeposits(2);
|
||||||
|
|
||||||
|
expect(tx1).to.be.ok;
|
||||||
|
expect(tx2).to.be.ok;
|
||||||
|
expect(tx3).to.be.ok;
|
||||||
|
await expect(tx1).to.emit(p2pix, "DepositClosed").withArgs(owner.address, 0);
|
||||||
|
await expect(tx2).to.emit(p2pix, "DepositClosed").withArgs(owner.address, 1);
|
||||||
|
await expect(tx3).to.emit(p2pix, "DepositClosed").withArgs(owner.address, 2);
|
||||||
|
expect(oldState1.valid).to.be.true;
|
||||||
|
expect(oldState2.valid).to.be.true;
|
||||||
|
expect(oldState3.valid).to.be.true;
|
||||||
|
expect(newState1.valid).to.be.false;
|
||||||
|
expect(newState2.valid).to.be.false;
|
||||||
|
expect(newState3.valid).to.be.false;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
describe("Release", async () => {
|
describe("Release", async () => {
|
||||||
// it("should revert if lock has expired or has already been released")
|
// it("should revert if lock has expired or has already been released")
|
||||||
@ -492,17 +711,18 @@ describe("P2PIX", () => {
|
|||||||
// LOCK RELAYER == RELEASE RELAYER (check userRecord storage update)
|
// LOCK RELAYER == RELEASE RELAYER (check userRecord storage update)
|
||||||
// )}
|
// )}
|
||||||
});
|
});
|
||||||
describe("Unlock Expired Locks", async () => {
|
describe("Unexpire Locks", async () => {
|
||||||
// it("should revert if lock isn't expired")
|
// it("should revert if lock isn't expired")
|
||||||
// it("should unlock expired locks, update storage and emit events")
|
// it("should unlock expired locks, update storage and emit events")
|
||||||
// CHECK FOR userRecord STORAGE UPDATE
|
// CHECK FOR userRecord STORAGE UPDATE
|
||||||
|
// test method through lock fx
|
||||||
|
// test method through withdraw fx
|
||||||
});
|
});
|
||||||
describe("Seller Withdraw", async () => {
|
describe("Seller Withdraw", async () => {
|
||||||
// it("should revert if the msg.sender isn't the deposit's seller")
|
// it("should revert if the msg.sender isn't the deposit's seller")
|
||||||
// it -> withdraw remaining funds from deposit
|
// it -> withdraw remaining funds from deposit
|
||||||
// CHECK UNEXPIRE LOCKS
|
|
||||||
});
|
});
|
||||||
describe("Seller Allowlist Settings", async () => {
|
describe("Allowlist Settings", async () => {
|
||||||
// it -> set root of seller's allowlist
|
// it -> set root of seller's allowlist
|
||||||
// (test msg.sender != seller error)
|
// (test msg.sender != seller error)
|
||||||
// i.e., set it in the fixture
|
// i.e., set it in the fixture
|
||||||
|
@ -12,4 +12,6 @@ export enum P2PixErrors {
|
|||||||
TokenDenied = "TokenDenied",
|
TokenDenied = "TokenDenied",
|
||||||
NoTokens = "NoTokens",
|
NoTokens = "NoTokens",
|
||||||
LengthMismatch = "LengthMismatch",
|
LengthMismatch = "LengthMismatch",
|
||||||
|
AddressDenied = "AddressDenied",
|
||||||
|
AmountNotAllowed = "AmountNotAllowed",
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers";
|
import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers";
|
||||||
import { BigNumber, Signer } from "ethers";
|
import { BigNumber, Signer } from "ethers";
|
||||||
import { ethers } from "hardhat";
|
import { ethers } from "hardhat";
|
||||||
|
import keccak256 from "keccak256";
|
||||||
|
import { MerkleTree } from "merkletreejs";
|
||||||
|
|
||||||
// import keccak256 from "keccak256";
|
|
||||||
// import { MerkleTree } from "merkletreejs";
|
|
||||||
import {
|
import {
|
||||||
MockToken,
|
MockToken,
|
||||||
P2PIX,
|
P2PIX,
|
||||||
@ -33,9 +33,8 @@ export interface Lock {
|
|||||||
export interface P2pixFixture {
|
export interface P2pixFixture {
|
||||||
p2pix: P2PIX;
|
p2pix: P2PIX;
|
||||||
erc20: MockToken;
|
erc20: MockToken;
|
||||||
// proof: string[];
|
proof: string[];
|
||||||
// wrongProof: string[];
|
merkleRoot: string;
|
||||||
// merkleRoot: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RepFixture {
|
export interface RepFixture {
|
||||||
@ -121,5 +120,24 @@ export async function p2pixFixture(): Promise<P2PixAndReputation> {
|
|||||||
[true],
|
[true],
|
||||||
)) as P2PIX;
|
)) as P2PIX;
|
||||||
|
|
||||||
return { reputation, erc20, p2pix };
|
const signers = await ethers.getSigners();
|
||||||
|
const whitelisted = signers.slice(0, 2);
|
||||||
|
const leaves = whitelisted.map(account =>
|
||||||
|
padBuffer(account.address),
|
||||||
|
);
|
||||||
|
const tree = new MerkleTree(leaves, keccak256, {
|
||||||
|
sort: true,
|
||||||
|
});
|
||||||
|
const merkleRoot: string = tree.getHexRoot();
|
||||||
|
const proof: string[] = tree.getHexProof(
|
||||||
|
padBuffer(whitelisted[0].address),
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
reputation,
|
||||||
|
erc20,
|
||||||
|
p2pix,
|
||||||
|
merkleRoot,
|
||||||
|
proof,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user