Skip to content

Commit

Permalink
[Plugin] add some tests for plugin fee && update snapshots
Browse files Browse the repository at this point in the history
  • Loading branch information
IliaAzhel committed Oct 7, 2024
1 parent 41ab42f commit 8e5967b
Show file tree
Hide file tree
Showing 11 changed files with 301 additions and 211 deletions.
18 changes: 11 additions & 7 deletions src/plugin/contracts/AlgebraBasePluginV2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,16 @@ contract AlgebraBasePluginV2 is SlidingFeePlugin, FarmingProxyPlugin, Volatility
return IAlgebraPlugin.afterModifyPosition.selector;
}

function beforeSwap(address, address, bool zeroToOne, int256, uint160, bool, bytes calldata) external override onlyPool returns (bytes4, uint24, uint24) {
( , int24 currentTick, , ) = _getPoolState();
function beforeSwap(
address,
address,
bool zeroToOne,
int256,
uint160,
bool,
bytes calldata
) external override onlyPool returns (bytes4, uint24, uint24) {
(, int24 currentTick, , ) = _getPoolState();
int24 lastTick = _getLastTick();
uint16 newFee = _getFeeAndUpdateFactors(zeroToOne, currentTick, lastTick);

Expand All @@ -70,8 +78,4 @@ contract AlgebraBasePluginV2 is SlidingFeePlugin, FarmingProxyPlugin, Volatility
_updatePluginConfigInPool(defaultPluginConfig); // should not be called, reset config
return IAlgebraPlugin.afterFlash.selector;
}

function getCurrentFee() external view returns (uint16 fee) {
(, , fee, ) = _getPoolState();
}
}
}
4 changes: 3 additions & 1 deletion src/plugin/contracts/test/SlidingFeeTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ pragma solidity =0.8.20;
import '../plugins/SlidingFeePlugin.sol';

contract SlidingFeeTest is SlidingFeePlugin {
event Fee(uint16 fee);
uint8 public constant override defaultPluginConfig = 0;
constructor() BasePlugin(msg.sender, msg.sender, msg.sender) {}

function getFeeForSwap(bool zeroToOne, int24 lastTick, int24 currentTick) external returns (uint16 fee) {
fee = _getFeeAndUpdateFactors(zeroToOne, currentTick, lastTick);
emit Fee(fee);
}

function getGasCostOfGetFeeForSwap(bool zeroToOne, int24 lastTick, int24 currentTick) external returns (uint256) {
Expand All @@ -26,4 +28,4 @@ contract SlidingFeeTest is SlidingFeePlugin {
function changeFactor(uint16 newFactor) external {
s_priceChangeFactor = newFactor;
}
}
}
8 changes: 0 additions & 8 deletions src/plugin/test/AlgebraBasePluginV1.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,14 +106,6 @@ describe('AlgebraBasePluginV1', () => {
expect((await mockPool.globalState()).pluginConfig).to.be.eq(defaultConfig);
});

it('resets config after afterSwap', async () => {
await mockPool.initialize(encodePriceSqrt(1, 1));
await mockPool.setPluginConfig(PLUGIN_FLAGS.AFTER_SWAP_FLAG);
expect((await mockPool.globalState()).pluginConfig).to.be.eq(PLUGIN_FLAGS.AFTER_SWAP_FLAG);
await mockPool.swapToTick(100);
expect((await mockPool.globalState()).pluginConfig).to.be.eq(defaultConfig);
});

it('resets config after beforeFlash', async () => {
await mockPool.setPluginConfig(PLUGIN_FLAGS.BEFORE_FLASH_FLAG);
expect((await mockPool.globalState()).pluginConfig).to.be.eq(PLUGIN_FLAGS.BEFORE_FLASH_FLAG);
Expand Down
52 changes: 44 additions & 8 deletions src/plugin/test/AlgebraBasePluginV2.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,14 +106,6 @@ describe('AlgebraBasePluginV2', () => {
expect((await mockPool.globalState()).pluginConfig).to.be.eq(defaultConfig);
});

it('resets config after afterSwap', async () => {
await mockPool.initialize(encodePriceSqrt(1, 1));
await mockPool.setPluginConfig(PLUGIN_FLAGS.AFTER_SWAP_FLAG);
expect((await mockPool.globalState()).pluginConfig).to.be.eq(PLUGIN_FLAGS.AFTER_SWAP_FLAG);
await mockPool.swapToTick(100);
expect((await mockPool.globalState()).pluginConfig).to.be.eq(defaultConfig);
});

it('resets config after beforeFlash', async () => {
await mockPool.setPluginConfig(PLUGIN_FLAGS.BEFORE_FLASH_FLAG);
expect((await mockPool.globalState()).pluginConfig).to.be.eq(PLUGIN_FLAGS.BEFORE_FLASH_FLAG);
Expand Down Expand Up @@ -318,6 +310,46 @@ describe('AlgebraBasePluginV2', () => {
});
});

describe('#SlidingFee', () => {

beforeEach('initialize pool', async () => {
await mockPool.setPlugin(plugin);
await initializeAtZeroTick(mockPool);
});

describe('#setPriceChangeFactor', () => {
it('works correct', async () => {
await plugin.setPriceChangeFactor(1500)
let factor = await plugin.s_priceChangeFactor()
expect(factor).to.be.equal(1500);
});

it('emit event', async () => {
await expect(plugin.setPriceChangeFactor(1500)).to.emit(plugin, "PriceChangeFactor");
});

it('fails if caller is not owner or manager', async () => {
await expect(plugin.connect(other).setPriceChangeFactor(1500)).to.be.reverted;
});
})

describe('#setBaseFee', () => {
it('works correct', async () => {
await plugin.setBaseFee(1500)
let baseFee = await plugin.s_baseFee()
expect(baseFee).to.be.equal(1500);
});

it('emit event', async () => {
await expect(plugin.setBaseFee(1500)).to.emit(plugin, "BaseFee");
});

it('fails if caller is not owner or manager', async () => {
await expect(plugin.connect(other).setBaseFee(1500)).to.be.reverted;
});
})
})

describe('#FarmingPlugin', () => {
describe('virtual pool tests', () => {
let virtualPoolMock: MockTimeVirtualPool;
Expand All @@ -328,6 +360,10 @@ describe('AlgebraBasePluginV2', () => {
virtualPoolMock = (await virtualPoolMockFactory.deploy()) as any as MockTimeVirtualPool;
});

it('returns pool address', async () => {
expect(await plugin.getPool()).to.be.eq(mockPool);
});

it('set incentive works', async () => {
await mockPool.setPlugin(plugin);
await plugin.setIncentive(virtualPoolMock);
Expand Down
125 changes: 125 additions & 0 deletions src/plugin/test/BasePluginV2Factory.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import { Wallet } from 'ethers';
import { ethers } from 'hardhat';
import { loadFixture } from '@nomicfoundation/hardhat-network-helpers';
import { expect } from './shared/expect';
import { ZERO_ADDRESS, pluginFactoryFixtureV2 } from './shared/fixtures';

import { BasePluginV2Factory, AlgebraBasePluginV2, MockFactory } from '../typechain';

describe('BasePluginV2Factory', () => {
let wallet: Wallet, other: Wallet;

let pluginFactory: BasePluginV2Factory;
let mockAlgebraFactory: MockFactory;

before('prepare signers', async () => {
[wallet, other] = await (ethers as any).getSigners();
});

beforeEach('deploy test volatilityOracle', async () => {
({ pluginFactory, mockFactory: mockAlgebraFactory } = await loadFixture(pluginFactoryFixtureV2));
});

describe('#Create plugin', () => {
it('only factory', async () => {
expect(pluginFactory.beforeCreatePoolHook(wallet.address, ZERO_ADDRESS, ZERO_ADDRESS, ZERO_ADDRESS, ZERO_ADDRESS, '0x')).to.be
.revertedWithoutReason;
});

it('factory can create plugin', async () => {
const pluginFactoryFactory = await ethers.getContractFactory('BasePluginV2Factory');
const pluginFactoryMock = (await pluginFactoryFactory.deploy(wallet.address)) as any as BasePluginV2Factory;

const pluginAddress = await pluginFactoryMock.beforeCreatePoolHook.staticCall(
wallet.address,
ZERO_ADDRESS,
ZERO_ADDRESS,
ZERO_ADDRESS,
ZERO_ADDRESS,
'0x'
);
await pluginFactoryMock.beforeCreatePoolHook(wallet.address, ZERO_ADDRESS, ZERO_ADDRESS, ZERO_ADDRESS, ZERO_ADDRESS, '0x');

const pluginMock = (await ethers.getContractFactory('AlgebraBasePluginV2')).attach(pluginAddress) as any as AlgebraBasePluginV2;
const baseFee = await pluginMock.s_baseFee();
expect(baseFee).to.be.not.eq(0);
});
});

describe('#CreatePluginForExistingPool', () => {
it('only if has role', async () => {
expect(pluginFactory.connect(other).createPluginForExistingPool(wallet.address, other.address)).to.be.revertedWithoutReason;
});

it('cannot create for nonexistent pool', async () => {
await expect(pluginFactory.createPluginForExistingPool(wallet.address, other.address)).to.be.revertedWith('Pool not exist');
});

it('can create for existing pool', async () => {
await mockAlgebraFactory.stubPool(wallet.address, other.address, other.address);

await pluginFactory.createPluginForExistingPool(wallet.address, other.address);
const pluginAddress = await pluginFactory.pluginByPool(other.address);
expect(pluginAddress).to.not.be.eq(ZERO_ADDRESS);
const pluginMock = (await ethers.getContractFactory('AlgebraBasePluginV2')).attach(pluginAddress) as any as AlgebraBasePluginV2;
const baseFee = await pluginMock.s_baseFee();
expect(baseFee).to.be.not.eq(0);
});

it('cannot create twice for existing pool', async () => {
await mockAlgebraFactory.stubPool(wallet.address, other.address, other.address);

await pluginFactory.createPluginForExistingPool(wallet.address, other.address);

await expect(pluginFactory.createPluginForExistingPool(wallet.address, other.address)).to.be.revertedWith('Already created');
});
});

describe('#Default base fee ', () => {
describe('#setDefaultBaseFee', () => {

it('fails if caller is not owner', async () => {
await expect(pluginFactory.connect(other).setDefaultBaseFee(1000)).to.be.revertedWith('Only administrator');
});

it('fails if try to set same value', async () => {
await expect(pluginFactory.connect(other).setDefaultBaseFee(500)).to.be.reverted;
});

it('updates defaultFeeConfiguration', async () => {
await pluginFactory.setDefaultBaseFee(1000);

const newFee = await pluginFactory.defaultBaseFee();

expect(newFee).to.eq(1000);
});

it('emits event', async () => {
await expect(pluginFactory.setDefaultBaseFee(1000))
.to.emit(pluginFactory, 'DefaultBaseFee')
.withArgs(1000);
});

});
});

describe('#setFarmingAddress', () => {
it('fails if caller is not owner', async () => {
await expect(pluginFactory.connect(other).setFarmingAddress(wallet.address)).to.be.revertedWith('Only administrator');
});

it('updates farmingAddress', async () => {
await pluginFactory.setFarmingAddress(other.address);
expect(await pluginFactory.farmingAddress()).to.eq(other.address);
});

it('emits event', async () => {
await expect(pluginFactory.setFarmingAddress(other.address)).to.emit(pluginFactory, 'FarmingAddress').withArgs(other.address);
});

it('cannot set current address', async () => {
await pluginFactory.setFarmingAddress(other.address);
await expect(pluginFactory.setFarmingAddress(other.address)).to.be.reverted;
});
});
});
44 changes: 43 additions & 1 deletion src/plugin/test/SlidingFee.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ describe('SlidingFee', () => {
expect(await slidingFeePlugin.s_priceChangeFactor()).to.be.eq(1000)
});

describe('#getSlidingFee', () => {
describe('#FeeFactors', () => {
beforeEach('set config', async () => {
await slidingFeePlugin.changeBaseFee(500)
await slidingFeePlugin.changeFactor(1000)
Expand Down Expand Up @@ -194,6 +194,48 @@ describe('SlidingFee', () => {

});

describe('#getSlidingFee', () => {

async function getFee(zto: boolean, lastTick: number, currentTick: number) : Promise<number>{
let tx = await slidingFeePlugin.getFeeForSwap(zto, lastTick, currentTick);
return (await tx.wait()).logs[0].args['fee']
}

beforeEach('set config', async () => {
await slidingFeePlugin.changeBaseFee(500)
await slidingFeePlugin.changeFactor(1000)
});

it("returns base fee value", async function () {
let fee = await getFee(false, 10000, 10000)
expect(fee).to.be.eq(500)
});

it("one to zero fee should be increased x1.5", async function () {
let feeOtZ = await getFee(false, 10000, 14055)
expect(feeOtZ).to.be.eq(750)
});

it("zero to one fee should be decreased x1.5", async function () {
let feeZtO = await getFee(true, 10000, 14054)
expect(feeZtO).to.be.eq(250)
});

it("handle overflow", async function () {
await slidingFeePlugin.changeBaseFee(50000)
let feeOtZ = await getFee(false, 10000,100000)
expect(feeOtZ).to.be.eq(65535)
});

it("MIN fee is 1 (0.0001%)", async function () {
await slidingFeePlugin.changeBaseFee(50000)
let feeOtZ = await getFee(true, 10000,100000)
expect(feeOtZ).to.be.eq(1)
});

})


describe('#getFee gas cost [ @skip-on-coverage ]', () => {
it('gas cost of same tick', async () => {
await snapshotGasCost(slidingFeePlugin.getGasCostOfGetFeeForSwap(true, 100, 100));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,4 @@ Array [
]
`;

exports[`AlgebraBasePluginV1 AlgebraBasePluginV1 external methods #changeFeeConfiguration feeConfig getter gas cost [ @skip-on-coverage ] 1`] = `23774`;
exports[`AlgebraBasePluginV1 AlgebraBasePluginV1 external methods #changeFeeConfiguration feeConfig getter gas cost [ @skip-on-coverage ] 1`] = `23708`;
Loading

0 comments on commit 8e5967b

Please sign in to comment.