Skip to content

Commit

Permalink
[Core] add plugin fee tests
Browse files Browse the repository at this point in the history
  • Loading branch information
IliaAzhel committed Jul 19, 2024
1 parent 19ad28e commit c8aa329
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 5 deletions.
23 changes: 18 additions & 5 deletions src/core/contracts/test/MockPoolPlugin.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import '../libraries/Plugins.sol';
contract MockPoolPlugin is IAlgebraPlugin, IAlgebraDynamicFeePlugin {
address public pool;
uint8 public selectorsDisableConfig;
uint24 public overrideFee;
uint24 public pluginFee;
bool public isDisabled;

constructor(address _pool) {
pool = _pool;
Expand Down Expand Up @@ -60,10 +63,19 @@ contract MockPoolPlugin is IAlgebraPlugin, IAlgebraDynamicFeePlugin {
selectorsDisableConfig = newSelectorsDisableConfig;
}

function handlePluginFee(uint256, uint256) external pure override returns (bytes4) {
function handlePluginFee(uint256, uint256) external view override returns (bytes4 selector) {
if (isDisabled) return selector;
return IAlgebraPlugin.handlePluginFee.selector;
}

function setPluginFees(uint24 _overrideFee, uint24 _pluginFee) external {
(overrideFee, pluginFee) = (_overrideFee, _pluginFee);
}

function disablePluginFeeHandle() external {
isDisabled = true;
}

/// @notice The hook called before the state of a pool is initialized
/// @param sender The initial msg.sender for the initialize call
/// @param sqrtPriceX96 The sqrt(price) of the pool as a Q64.96
Expand Down Expand Up @@ -97,8 +109,9 @@ contract MockPoolPlugin is IAlgebraPlugin, IAlgebraDynamicFeePlugin {
bytes calldata data
) external override returns (bytes4, uint24) {
emit BeforeModifyPosition(sender, recipient, bottomTick, topTick, desiredLiquidityDelta, data);
if (!Plugins.hasFlag(selectorsDisableConfig, Plugins.BEFORE_POSITION_MODIFY_FLAG)) return (IAlgebraPlugin.beforeModifyPosition.selector, 0);
return (IAlgebraPlugin.defaultPluginConfig.selector, 0);
if (!Plugins.hasFlag(selectorsDisableConfig, Plugins.BEFORE_POSITION_MODIFY_FLAG))
return (IAlgebraPlugin.beforeModifyPosition.selector, overrideFee);
return (IAlgebraPlugin.defaultPluginConfig.selector, overrideFee);
}

/// @notice The hook called after a position is modified
Expand Down Expand Up @@ -132,8 +145,8 @@ contract MockPoolPlugin is IAlgebraPlugin, IAlgebraDynamicFeePlugin {
bytes calldata data
) external override returns (bytes4, uint24, uint24) {
emit BeforeSwap(sender, recipient, zeroToOne, amountRequired, limitSqrtPrice, withPaymentInAdvance, data);
if (!Plugins.hasFlag(selectorsDisableConfig, Plugins.BEFORE_SWAP_FLAG)) return (IAlgebraPlugin.beforeSwap.selector, 0, 0);
return (IAlgebraPlugin.defaultPluginConfig.selector, 0, 0);
if (!Plugins.hasFlag(selectorsDisableConfig, Plugins.BEFORE_SWAP_FLAG)) return (IAlgebraPlugin.beforeSwap.selector, overrideFee, pluginFee);
return (IAlgebraPlugin.defaultPluginConfig.selector, overrideFee, pluginFee);
}

/// @notice The hook called after a swap
Expand Down
90 changes: 90 additions & 0 deletions src/core/test/AlgebraPool.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2430,6 +2430,96 @@ describe('AlgebraPool', () => {
});
});

describe('#pluginFee', () => {
let poolPlugin : MockPoolPlugin;

beforeEach('initialize the pool', async () => {
const MockPoolPluginFactory = await ethers.getContractFactory('MockPoolPlugin');
poolPlugin = (await MockPoolPluginFactory.deploy(await pool.getAddress())) as any as MockPoolPlugin;
await pool.setPlugin(poolPlugin);
await pool.setPluginConfig(255);
await pool.initialize(encodePriceSqrt(1, 1));
await mint(wallet.address, minTick, maxTick, expandTo18Decimals(1));
});

it('swap fails if plugin fee greater than override fee', async () => {
await poolPlugin.setPluginFees(3000, 4000);
await expect(swapExact0For1(expandTo18Decimals(1), wallet.address)).to.be.revertedWithCustomError(pool, 'incorrectPluginFee');
})

it('swap fails if plugin fee exceeds max value', async () => {
await poolPlugin.setPluginFees(1000001, 4000);
await expect(swapExact0For1(expandTo18Decimals(1), wallet.address)).to.be.revertedWithCustomError(pool, 'incorrectOverrideFee');
await expect(pool.burn(minTick, maxTick, expandTo18Decimals(1), '0x')).to.be.revertedWithCustomError(pool, 'incorrectOverrideFee');
})

it('swap fails if plugin return incorrect selector', async () => {
await poolPlugin.disablePluginFeeHandle();
await poolPlugin.setPluginFees(5000, 4000);
await expect(swapExact0For1(expandTo18Decimals(1), wallet.address)).to.be.revertedWithCustomError(pool, 'invalidPluginResponce') ;
})

it('works correct on swap', async () => {
await poolPlugin.setPluginFees(5000, 4000);
await swapExact0For1(expandTo18Decimals(1), wallet.address);
await swapExact0For1(expandTo18Decimals(1), wallet.address);
await swapExact1For0(expandTo18Decimals(1), wallet.address);
let pluginFees = await pool.getPluginFeePending();
expect(pluginFees[0]).to.be.eq(4n * 10n**15n);
expect(pluginFees[1]).to.be.eq(4n * 10n**15n)
})

it('works correct on swap, fee is 50%, 75%, 100%', async () => {
await poolPlugin.setPluginFees(500000, 500000);
await swapExact0For1(expandTo18Decimals(1), wallet.address);
await swapExact1For0(expandTo18Decimals(1), wallet.address);
let pluginFees = await pool.getPluginFeePending();
expect(pluginFees[1]).to.be.eq(expandTo18Decimals(1)/2n);

await poolPlugin.setPluginFees(750000, 750000);
await swapExact1For0(expandTo18Decimals(1), wallet.address);
pluginFees = await pool.getPluginFeePending();
expect(pluginFees[1]).to.be.eq(expandTo18Decimals(1)* 125n / 100n);

await poolPlugin.setPluginFees(1000000, 1000000);
await swapExact1For0(expandTo18Decimals(1), wallet.address);
pluginFees = await pool.getPluginFeePending();
expect(pluginFees[1]).to.be.eq(expandTo18Decimals(1)* 225n / 100n);
})

it('works correct on burn', async () => {
await poolPlugin.setPluginFees(6000, 0);
await pool.burn(minTick, maxTick, expandTo18Decimals(1), '0x')
let pluginFees = await pool.getPluginFeePending();
expect(pluginFees[0]).to.be.eq(6n * 10n**15n-1n);
expect(pluginFees[1]).to.be.eq(6n * 10n**15n-1n)
})

it('fees transfered to plugin', async () => {
await poolPlugin.setPluginFees(5000, 4000);
const pluginBalance0Before = await token0.balanceOf(poolPlugin);
const pluginBalance1Before = await token1.balanceOf(poolPlugin);
await swapExact0For1(expandTo18Decimals(1), wallet.address)
const pluginBalance0After = await token0.balanceOf(poolPlugin);
const pluginBalance1After = await token1.balanceOf(poolPlugin);
expect(pluginBalance0After - pluginBalance0Before).to.be.eq(4n * 10n**15n);
expect(pluginBalance1After - pluginBalance1Before).to.be.eq(0);
})

it('works correct with communityFee', async () => {
await poolPlugin.setPluginFees(5000, 4000);
await pool.setCommunityFee(500);
await swapExact0For1(expandTo18Decimals(1), wallet.address);
await swapExact0For1(expandTo18Decimals(1), wallet.address);
const communityFees = await pool.getCommunityFeePending();
const pluginFees = await pool.getPluginFeePending();

expect(communityFees[0]).to.be.eq(expandTo18Decimals(1) * 5n / 10000n); // 0.05%
expect(pluginFees[0]).to.be.eq(4n * 10n**15n);
})

})

describe('PermissionedActions', async () => {
describe('#setCommunityFee', () => {
beforeEach('initialize the pool', async () => {
Expand Down
5 changes: 5 additions & 0 deletions src/plugin/contracts/test/MockPool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ contract MockPool is IAlgebraPoolActions, IAlgebraPoolPermissionedActions, IAlge
revert('not implemented');
}

/// @inheritdoc IAlgebraPoolState
function getPluginFeePending() external pure override returns (uint128, uint128) {
revert('not implemented');
}

/// @inheritdoc IAlgebraPoolState
function fee() external pure returns (uint16) {
revert('not implemented');
Expand Down

0 comments on commit c8aa329

Please sign in to comment.