Skip to content

Commit

Permalink
test: add simulations for swapping the debt
Browse files Browse the repository at this point in the history
  • Loading branch information
kkirka committed Mar 6, 2023
1 parent 59318f6 commit d22570a
Showing 1 changed file with 209 additions and 0 deletions.
209 changes: 209 additions & 0 deletions script/hardhat/fork/vip-99.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers";
import { expect } from "chai";
import { BigNumber } from "ethers";
import { parseEther, parseUnits } from "ethers/lib/utils";
import { ethers } from "hardhat";

import {
Comptroller,
IERC20Upgradeable,
PriceOracle,
SwapDebtDelegate,
VBep20,
VBep20Delegate,
} from "../../../typechain";
import { forking, pretendExecutingVip, testVip } from "./vip-framework";
import { ProposalType } from "./vip-framework/types";
import { initMainnetUser, makeProposal } from "./vip-framework/utils";

const COMPTROLLER = "0xfd36e2c2a6789db23113685031d7f16329158384";
const BNB_BRIDGE_EXPLOITER = "0x489A8756C18C0b8B24EC2a2b9FF3D4d447F79BEc";
const VBUSD = "0x95c78222B3D6e262426483D42CfA53685A67Ab9D";
const VUSDC = "0xecA88125a5ADbe82614ffC12D0DB554E2e2867C8";
const VUSDT = "0xfD5840Cd36d94D7229439859C0112a4185BC0255";
const VETH = "0xf508fCD89b8bd15579dc79A6827cB4686A3592c8";
const VBTC = "0x882C173bC7Ff3b7786CA16dfeD3DFFfb9Ee7847B";
const CONFIGURE_ATTACKER_COMPTROLLER_IMPL = "0xAE37464537fDa217258Bb2Cd70e4f8ffC7E95790";
const NEW_COMPTROLLER_IMPL = "0x909dd16b24CEf96c7be13065a9a0EAF8A126FFa5";
const NEW_VTOKEN_IMPL = "0x10FB44C481F87cb4F3ce8DE11fFd16e00EC5B670";
const SWAP_DEBT_DELEGATE = "0x2B16DB59c6f20672C0DB46b80361E9Ca1CD8a43a";
const BINANCE_MULTISIG = "0x6d46692f809d485A033dA95B19b556E3Ff0ACb12";

const vip99 = () => {
const meta = {
version: "v2",
title: "VIP-99 Delegate borrowing",
description: `
`,
forDescription: "I agree that Venus Protocol should proceed with ",
againstDescription: "I do not think that Venus Protocol should proceed with ",
abstainDescription: "I am indifferent to whether Venus Protocol proceeds with ",
};

return makeProposal(
[
{
target: COMPTROLLER,
signature: "_setPendingImplementation(address)",
params: [CONFIGURE_ATTACKER_COMPTROLLER_IMPL],
},
{
target: CONFIGURE_ATTACKER_COMPTROLLER_IMPL,
signature: "_become(address)",
params: [COMPTROLLER],
},
{
target: COMPTROLLER,
signature: "setDelegateForBNBHacker(address)",
params: [SWAP_DEBT_DELEGATE],
},
{
target: COMPTROLLER,
signature: "_setPendingImplementation(address)",
params: [NEW_COMPTROLLER_IMPL],
},
{
target: NEW_COMPTROLLER_IMPL,
signature: "_become(address)",
params: [COMPTROLLER],
},
...[VBUSD, VUSDC, VUSDT, VBTC, VETH].map((vToken: string) => {
return {
target: vToken,
signature: "_setImplementation(address,bool,bytes)",
params: [NEW_VTOKEN_IMPL, false, "0x"],
};
}),
],
meta,
ProposalType.REGULAR,
);
};

forking(25918391, () => {
testVip("VIP-99 Delegate borrowing", vip99(), {
proposer: "0xc444949e0054a23c44fc45789738bdf64aed2391",
supporter: "0x55A9f5374Af30E3045FB491f1da3C2E8a74d168D",
});
});

// Ressetting the fork to prevent oracle prices from getting stale
forking(25918391, () => {
let comptroller: Comptroller;
let busd: IERC20Upgradeable;
let usdt: IERC20Upgradeable;
let btc: IERC20Upgradeable;
let vBUSD: VBep20Delegate;
let vUSDC: VBep20Delegate;
let vUSDT: VBep20Delegate;
let vBTC: VBep20Delegate;
let vETH: VBep20Delegate;
let swapDebtDelegate: SwapDebtDelegate;
let oracle: PriceOracle;

before(async () => {
comptroller = await ethers.getContractAt("Comptroller", COMPTROLLER);
[vBUSD, vUSDC, vUSDT, vBTC, vETH] = await Promise.all(
[VBUSD, VUSDC, VUSDT, VBTC, VETH].map((address: string) => {
return ethers.getContractAt("VBep20Delegate", address);
}),
);
[busd, , usdt, btc] = await Promise.all(
[vBUSD, vUSDC, vUSDT, vBTC, vETH].map(async (vToken: VBep20) => {
const underlying = await vToken.underlying();
return ethers.getContractAt("IERC20Upgradeable", underlying);
}),
);
const oracleAddress = await comptroller.oracle();
oracle = await ethers.getContractAt("PriceOracle", oracleAddress);
swapDebtDelegate = await ethers.getContractAt("SwapDebtDelegate", SWAP_DEBT_DELEGATE);
await pretendExecutingVip(vip99());
});

describe("Post-VIP contracts status", async () => {
it("updates vBUSD, vUSDC, vUSDT, vBTC, vETH implementation to the new version", async () => {
for (const vToken of [vBUSD, vUSDC, vUSDT, vBTC, vETH]) {
expect(await vToken.implementation()).to.equal(NEW_VTOKEN_IMPL);
}
});

it("sets Comptroller implementation to the new version", async () => {
expect(await comptroller.comptrollerImplementation()).to.equal(NEW_COMPTROLLER_IMPL);
});

it("sets the delegate for BNB bridge exploiter", async () => {
expect(await comptroller.approvedDelegates(BNB_BRIDGE_EXPLOITER, SWAP_DEBT_DELEGATE)).to.equal(true);
});
});

describe("BNB bridge exploiter debt swap", async () => {
let binanceMultisig: SignerWithAddress;
let repayAmount: BigNumber;

before(async () => {
binanceMultisig = await initMainnetUser(BINANCE_MULTISIG, parseEther("1"));
await swapDebtDelegate.connect(binanceMultisig).acceptOwnership();
});

beforeEach(async () => {
const busdHolder = await initMainnetUser(BNB_BRIDGE_EXPLOITER, parseEther("1"));
repayAmount = parseUnits("1000000", 18); // one million BUSD
await busd.connect(busdHolder).transfer(BINANCE_MULTISIG, repayAmount);
await busd.connect(binanceMultisig).approve(swapDebtDelegate.address, repayAmount);
});

it("swaps BUSD debt to USDT debt", async () => {
const tx = await swapDebtDelegate
.connect(binanceMultisig)
.swapDebt(BNB_BRIDGE_EXPLOITER, vBUSD.address, vUSDT.address, repayAmount);
const busdPrice = await oracle.getUnderlyingPrice(VBUSD);
const usdtPrice = await oracle.getUnderlyingPrice(VUSDT);
const borrowedAmount = repayAmount.mul(busdPrice).div(usdtPrice);
expect(borrowedAmount).to.equal(parseUnits("999880.752177709989496153", 18));
await expect(tx).to.emit(vBUSD, "RepayBorrow").withArgs(
SWAP_DEBT_DELEGATE, // payer
BNB_BRIDGE_EXPLOITER, // borrower
repayAmount,
parseUnits("62570837.271361800039742166", 18),
parseUnits("118656538.075710219424628656", 18),
);

await expect(tx).to.emit(vUSDT, "Borrow").withArgs(
BNB_BRIDGE_EXPLOITER, // borrower
borrowedAmount,
parseUnits("51791626.908005102781624591", 18), // account's borrows
parseUnits("146773356.517479562888182714", 18), // total market borrows
);

expect(await busd.balanceOf(BINANCE_MULTISIG)).to.equal(0);
expect(await usdt.balanceOf(BINANCE_MULTISIG)).to.equal(parseUnits("999880.752177709989496153"));
});

it("swaps BUSD debt to BTC debt", async () => {
const tx = await swapDebtDelegate
.connect(binanceMultisig)
.swapDebt(BNB_BRIDGE_EXPLOITER, vBUSD.address, vBTC.address, repayAmount);
const busdPrice = await oracle.getUnderlyingPrice(VBUSD);
const btcPrice = await oracle.getUnderlyingPrice(VBTC);
const borrowedAmount = repayAmount.mul(busdPrice).div(btcPrice);
expect(borrowedAmount).to.equal(parseUnits("41.467723055552676044", 18));
await expect(tx).to.emit(vBUSD, "RepayBorrow").withArgs(
SWAP_DEBT_DELEGATE, // payer
BNB_BRIDGE_EXPLOITER, // borrower
repayAmount,
parseUnits("61570838.645557291459272559", 18), // account's borrows
parseUnits("117656540.681673105060252768", 18), // total market borrows
);

await expect(tx).to.emit(vBTC, "Borrow").withArgs(
BNB_BRIDGE_EXPLOITER, // borrower
borrowedAmount,
borrowedAmount, // there were no Bitcoin borrows before
parseUnits("2115.100441504922154141", 18), // total market borrows
);

expect(await busd.balanceOf(BINANCE_MULTISIG)).to.equal(0);
expect(await btc.balanceOf(BINANCE_MULTISIG)).to.equal(parseUnits("41.467723055552676044"));
});
});
});

0 comments on commit d22570a

Please sign in to comment.