Skip to content

Commit

Permalink
tests: add a test case for ToucanProtocol#31
Browse files Browse the repository at this point in the history
This test case first creates the state described in the ticket as a setup step, ie, that the lowest scored TCO2 is not present in the NCT pool. Then it tests that autoRetire works, even if the lowest scored TCO2 is not in the pool.
  • Loading branch information
danceratopz committed Aug 9, 2022
1 parent d5e6ce8 commit 00b7d33
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 10 deletions.
85 changes: 76 additions & 9 deletions test/OffsetHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@ import {

import * as hardhatContracts from "../utils/toucanContracts.json";
import * as poolContract from "../artifacts/contracts/interfaces/IToucanPoolToken.sol/IToucanPoolToken.json";
import * as carbonOffsetsContract from "../artifacts/contracts/interfaces/IToucanCarbonOffsets.sol/IToucanCarbonOffsets.json";
import {
IToucanPoolToken,
OffsetHelper,
OffsetHelper__factory,
Swapper,
Swapper__factory,
} from "../typechain";
import addresses from "../utils/addresses";
import addresses, { whaleAddresses } from "../utils/addresses";
import { Contract } from "ethers";
import { usdcABI, wethABI, wmaticABI } from "../utils/ABIs";

Expand Down Expand Up @@ -85,13 +86,31 @@ describe("Offset Helper - autoOffset", function () {
]
);

await Promise.all(
addrs.map(async (addr) => {
await addr.sendTransaction({
to: addr2.address,
value: (await addr.getBalance()).sub(parseEther("1.0")),
});
})
// Transfer a large amount of MATIC and NCT to the test account via account impersonation.
await network.provider.request({
method: "hardhat_impersonateAccount",
params: [whaleAddresses.matic],
});
const maticWhale = ethers.provider.getSigner(whaleAddresses.matic);
await maticWhale.sendTransaction({
to: addr2.address,
value: (await maticWhale.getBalance()).sub(parseEther("1.0")),
});

// Note: The swapper fails when trying to exchange such a large amount of NCT.
await network.provider.request({
method: "hardhat_impersonateAccount",
params: [whaleAddresses.nct],
});
const addrNctWhale = ethers.provider.getSigner(whaleAddresses.nct);
const nctWhaleSigner = new ethers.Contract(
addresses.nct,
hardhatContracts.contracts.NatureCarbonTonne.abi,
addrNctWhale
);
await nctWhaleSigner.transfer(
addr2.address,
await nctWhaleSigner.balanceOf(whaleAddresses.nct)
);

await swapper.swap(addresses.weth, parseEther("20.0"), {
Expand Down Expand Up @@ -298,7 +317,7 @@ describe("Offset Helper - autoOffset", function () {
).to.be.revertedWith("Insufficient TCO2 balance");
});

it("Should retire using an NCT deposit", async function () {
it("Should retire using a BCT deposit", async function () {
await (await bct.approve(offsetHelper.address, parseEther("1.0"))).wait();

await (
Expand All @@ -319,6 +338,54 @@ describe("Offset Helper - autoOffset", function () {

await expect(offsetHelper.autoRetire(tco2s, amounts)).to.not.be.reverted;
});

it("Should retire using an NCT deposit, even if the first scored TCO2 is not in pool", async function () {
const scoredTCO2s = await nct.getScoredTCO2s();
const lowestScoredTCO2 = new ethers.Contract(
scoredTCO2s[0],
carbonOffsetsContract.abi,
addr2
);
const lowestScoredTCO2Balance = await lowestScoredTCO2.balanceOf(
addresses.nct
);

// Skip setup if the oldest tco2's balance in the pool is already 0.
if (formatEther(lowestScoredTCO2Balance) !== "0.0") {
// Setup: If the oldest tco2 balance is non-zero, remove all its tokens from the pool via a redeem.
// Ensure that addr2 has enough NCT to redeem all of the lowestScoredTCO2 or setup will fail.
expect(await nct.balanceOf(addr2.address)).to.be.above(
await lowestScoredTCO2.balanceOf(addresses.nct)
);

await nct.approve(offsetHelper.address, lowestScoredTCO2Balance);

await offsetHelper.deposit(addresses.nct, lowestScoredTCO2Balance);

await offsetHelper.autoRedeem(addresses.nct, lowestScoredTCO2Balance);
}

// Ensure the test condition is met.
expect(await lowestScoredTCO2.balanceOf(addresses.nct)).to.equal(0);

await nct.approve(offsetHelper.address, parseEther("1.0"));

await offsetHelper.deposit(addresses.nct, parseEther("0.0005"));

const redeemReceipt = await (
await offsetHelper.autoRedeem(addresses.nct, parseEther("0.0005"))
).wait();

if (!redeemReceipt.events) {
return;
}
const tco2s =
redeemReceipt.events[redeemReceipt.events.length - 1].args?.tco2s;
const amounts =
redeemReceipt.events[redeemReceipt.events.length - 1].args?.amounts;

await expect(offsetHelper.autoRetire(tco2s, amounts)).to.not.be.reverted;
});
});

describe("Testing deposit() and withdraw()", function () {
Expand Down
11 changes: 10 additions & 1 deletion utils/addresses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ interface IfcAddresses {
wmatic: string;
}

const addresses: IfcAddresses = {
interface IfcWhaleAddresses {
matic: string;
nct: string;
}
export const addresses: IfcAddresses = {
myAddress: "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266",
bct: "0x2F800Db0fdb5223b3C3f354886d907A671414A7F",
nct: "0xD838290e877E0188a4A44700463419ED96c16107",
Expand All @@ -16,6 +20,11 @@ const addresses: IfcAddresses = {
wmatic: "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270",
};

export const whaleAddresses: IfcWhaleAddresses = {
matic: "0xe7804c37c13166fF0b37F5aE0BB07A3aEbb6e245",
nct: "0x4b3ebae392e8b90a9b13068e90b27d9c41abc3c8",
};

export const mumbaiAddresses: IfcAddresses = {
myAddress: "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266",
bct: "0xf2438A14f668b1bbA53408346288f3d7C71c10a1",
Expand Down

0 comments on commit 00b7d33

Please sign in to comment.