Skip to content

Instantly share code, notes, and snippets.

@spalen0
Created February 21, 2023 07:57
Show Gist options
  • Save spalen0/1bfc6379f00a9d73a1285367e8ccd669 to your computer and use it in GitHub Desktop.
Save spalen0/1bfc6379f00a9d73a1285367e8ccd669 to your computer and use it in GitHub Desktop.
Temple DAO exit vault test
it("correctly wrapped exit to token with different recipient", async () => {
await bootstrapReserves();
const amount = ethers.utils.parseEther("1000");
// Can't get a quote for 0
{
const quoteData = {
...(await ovToken.exitQuote(100, underlyingInvestToken.address, ZERO_SLIPPAGE, ZERO_DEADLINE)).quoteData,
investmentTokenAmount: BigNumber.from(0),
};
await expect(ovToken.connect(bob).exitToToken(quoteData, alan.getAddress()))
.to.revertedWithCustomError(ovToken, "ExpectedNonZero");
}
// Bob has no investment token - so it fails
{
const quote = await ovToken.exitQuote(amount, oToken.address, ZERO_SLIPPAGE, ZERO_DEADLINE);
// Bob doesn't have any ovToken's yet
await expect(ovToken.connect(bob).exitToToken(quote.quoteData, alan.getAddress()))
.to.be.revertedWithCustomError(ovToken, "InsufficientBalance")
.withArgs(ovToken.address, amount, 0);
}
{
// Mint oToken to bob and invest
const reservesAmount = amount.mul(10);
await oToken.connect(operator).mint(bob.getAddress(), reservesAmount);
await oToken.connect(bob).approve(ovToken.address, reservesAmount);
const quote = await ovToken.investQuote(reservesAmount, oToken.address, ZERO_SLIPPAGE, ZERO_DEADLINE);
await ovToken.connect(bob).investWithToken(quote.quoteData);
// Also mint the ovToken some underlyingInvestToken so positions can exit
await underlyingExitToken.connect(operator).mint(oToken.address, ethers.utils.parseEther("100000"));
}
// Sell to the reserve token
{
const oTokenSupply = await oToken.totalSupply();
const ovTokenSupply = await ovToken.totalSupply();
const osReservesSupply = await ovToken.totalReserves();
const quote = await ovToken.exitQuote(amount, oToken.address, ZERO_SLIPPAGE, ZERO_DEADLINE);
await expectBalancesChangeBy(async () => {
await expect(ovToken.connect(bob).exitToToken(quote.quoteData, alan.getAddress()))
.to.emit(ovToken, "Transfer")
.withArgs(await bob.getAddress(), ZERO_ADDRESS, amount)
.to.emit(ovToken, "VestedReservesRemoved")
.withArgs(quote.quoteData.expectedToTokenAmount)
.to.emit(ovToken, "Exited")
.withArgs(await bob.getAddress(), amount, oToken.address, quote.quoteData.expectedToTokenAmount, await alan.getAddress());
},
[oToken, alan, quote.quoteData.expectedToTokenAmount],
[oToken, ovToken, quote.quoteData.expectedToTokenAmount.mul(-1)],
[ovToken, bob, amount.mul(-1)],
);
expect(await oToken.totalSupply()).eq(oTokenSupply);
expect(await ovToken.totalReserves()).eq(osReservesSupply.sub(quote.quoteData.expectedToTokenAmount));
expect(await ovToken.totalSupply()).eq(ovTokenSupply.sub(amount));
}
// Sell to a different token
{
const oTokenSupply = await oToken.totalSupply();
const ovTokenSupply = await ovToken.totalSupply();
const osReservesSupply = await ovToken.totalReserves();
const quote = await ovToken.exitQuote(amount, underlyingExitToken.address, ZERO_SLIPPAGE, ZERO_DEADLINE);
const expectedReserveAmount = await ovToken.sharesToReserves(amount);
await expectBalancesChangeBy(async () => {
await expect(ovToken.connect(bob).exitToToken(quote.quoteData, alan.getAddress()))
.to.emit(ovToken, "Transfer")
.withArgs(await bob.getAddress(), ZERO_ADDRESS, amount)
.to.emit(ovToken, "VestedReservesRemoved")
.withArgs(expectedReserveAmount)
.to.emit(ovToken, "Exited")
.withArgs(await bob.getAddress(), amount, underlyingExitToken.address, quote.quoteData.expectedToTokenAmount, await alan.getAddress())
.to.emit(oToken, "Exited")
.withArgs(ovToken.address, expectedReserveAmount, underlyingExitToken.address, quote.quoteData.expectedToTokenAmount, await alan.getAddress())
.to.emit(underlyingExitToken, "Transfer")
.withArgs(oToken.address, await alan.getAddress(), quote.quoteData.expectedToTokenAmount);
},
[underlyingExitToken, alan, quote.quoteData.expectedToTokenAmount],
[underlyingExitToken, oToken, quote.quoteData.expectedToTokenAmount.mul(-1)],
[ovToken, bob, amount.mul(-1)],
[oToken, ovToken, expectedReserveAmount.mul(-1)],
);
expect(await oToken.totalSupply()).eq(oTokenSupply.sub(expectedReserveAmount));
expect(await ovToken.totalReserves()).eq(osReservesSupply.sub(expectedReserveAmount));
expect(await ovToken.totalSupply()).eq(ovTokenSupply.sub(amount));
}
// Check slippage is applied for reserve token
{
// A quote for 0 slippage
const quoteData = (await ovToken.exitQuote(amount, oToken.address, ZERO_SLIPPAGE, ZERO_DEADLINE)).quoteData;
const minAmountOut = quoteData.minToTokenAmount.add(1);
const manualQuoteData = {
...quoteData,
minToTokenAmount: minAmountOut
};
// Fails when asking for too much
await expect(ovToken.connect(bob).exitToToken(manualQuoteData, alan.getAddress()))
.to.revertedWithCustomError(ovToken, "Slippage")
.withArgs(minAmountOut, quoteData.expectedToTokenAmount);
// Works with the right min amount
await expect(ovToken.connect(bob).exitToToken(quoteData, alan.getAddress()))
.to.emit(ovToken, "Exited");
}
// Check slippage is applied for other token
{
// A quote for 0 slippage
const quoteData = (await ovToken.exitQuote(amount, underlyingExitToken.address, ZERO_SLIPPAGE, ZERO_DEADLINE)).quoteData;
const minAmountOut = quoteData.minToTokenAmount.add(1);
const manualQuoteData = {
...quoteData,
minToTokenAmount: minAmountOut
};
// Fails with slippage
await expect(ovToken.connect(bob).exitToToken(manualQuoteData, alan.getAddress()))
.to.revertedWithCustomError(ovToken, "Slippage")
.withArgs(minAmountOut, quoteData.expectedToTokenAmount);
// Works with the right min amount
await expect(ovToken.connect(bob).exitToToken(quoteData, alan.getAddress()))
.to.emit(ovToken, "Exited");
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment