Add a "fees" section to the ERC4626 guide (#4054)

Co-authored-by: Francisco Giordano <fg@frang.io>
This commit is contained in:
Hadrien Croubois
2023-02-24 15:49:10 +01:00
committed by GitHub
parent 62dbb1b06a
commit d5581531de
5 changed files with 284 additions and 0 deletions

View File

@ -4,6 +4,7 @@ const { expect } = require('chai');
const ERC20Decimals = artifacts.require('$ERC20DecimalsMock');
const ERC4626 = artifacts.require('$ERC4626');
const ERC4626OffsetMock = artifacts.require('$ERC4626OffsetMock');
const ERC4626FeesMock = artifacts.require('$ERC4626FeesMock');
contract('ERC4626', function (accounts) {
const [holder, recipient, spender, other, user1, user2] = accounts;
@ -489,6 +490,132 @@ contract('ERC4626', function (accounts) {
});
}
describe('ERC4626Fees', function () {
const feeBasePoint = web3.utils.toBN(5e3);
const amountWithoutFees = web3.utils.toBN(10000);
const fees = amountWithoutFees.mul(feeBasePoint).divn(1e5);
const amountWithFees = amountWithoutFees.add(fees);
describe('input fees', function () {
beforeEach(async function () {
this.token = await ERC20Decimals.new(name, symbol, 18);
this.vault = await ERC4626FeesMock.new(
name + ' Vault',
symbol + 'V',
this.token.address,
feeBasePoint,
other,
0,
constants.ZERO_ADDRESS,
);
await this.token.$_mint(holder, constants.MAX_INT256);
await this.token.approve(this.vault.address, constants.MAX_INT256, { from: holder });
});
it('deposit', async function () {
expect(await this.vault.previewDeposit(amountWithFees)).to.be.bignumber.equal(amountWithoutFees);
({ tx: this.tx } = await this.vault.deposit(amountWithFees, recipient, { from: holder }));
});
it('mint', async function () {
expect(await this.vault.previewMint(amountWithoutFees)).to.be.bignumber.equal(amountWithFees);
({ tx: this.tx } = await this.vault.mint(amountWithoutFees, recipient, { from: holder }));
});
afterEach(async function () {
// get total
await expectEvent.inTransaction(this.tx, this.token, 'Transfer', {
from: holder,
to: this.vault.address,
value: amountWithFees,
});
// redirect fees
await expectEvent.inTransaction(this.tx, this.token, 'Transfer', {
from: this.vault.address,
to: other,
value: fees,
});
// mint shares
await expectEvent.inTransaction(this.tx, this.vault, 'Transfer', {
from: constants.ZERO_ADDRESS,
to: recipient,
value: amountWithoutFees,
});
// deposit event
await expectEvent.inTransaction(this.tx, this.vault, 'Deposit', {
sender: holder,
owner: recipient,
assets: amountWithFees,
shares: amountWithoutFees,
});
});
});
describe('output fees', function () {
beforeEach(async function () {
this.token = await ERC20Decimals.new(name, symbol, 18);
this.vault = await ERC4626FeesMock.new(
name + ' Vault',
symbol + 'V',
this.token.address,
0,
constants.ZERO_ADDRESS,
5e3, // 5%
other,
);
await this.token.$_mint(this.vault.address, constants.MAX_INT256);
await this.vault.$_mint(holder, constants.MAX_INT256);
});
it('redeem', async function () {
expect(await this.vault.previewRedeem(amountWithFees)).to.be.bignumber.equal(amountWithoutFees);
({ tx: this.tx } = await this.vault.redeem(amountWithFees, recipient, holder, { from: holder }));
});
it('withdraw', async function () {
expect(await this.vault.previewWithdraw(amountWithoutFees)).to.be.bignumber.equal(amountWithFees);
({ tx: this.tx } = await this.vault.withdraw(amountWithoutFees, recipient, holder, { from: holder }));
});
afterEach(async function () {
// withdraw principal
await expectEvent.inTransaction(this.tx, this.token, 'Transfer', {
from: this.vault.address,
to: recipient,
value: amountWithoutFees,
});
// redirect fees
await expectEvent.inTransaction(this.tx, this.token, 'Transfer', {
from: this.vault.address,
to: other,
value: fees,
});
// mint shares
await expectEvent.inTransaction(this.tx, this.vault, 'Transfer', {
from: holder,
to: constants.ZERO_ADDRESS,
value: amountWithFees,
});
// withdraw event
await expectEvent.inTransaction(this.tx, this.vault, 'Withdraw', {
sender: holder,
receiver: recipient,
owner: holder,
assets: amountWithoutFees,
shares: amountWithFees,
});
});
});
});
/// Scenario inspired by solmate ERC4626 tests:
/// https://github.com/transmissions11/solmate/blob/main/src/test/ERC4626.t.sol
it('multiple mint, deposit, redeem & withdrawal', async function () {