Skip to content

Fix autoRetire when the lowest scored tco2 is not present in the pool #31 #32

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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