Skip to content

Commit

Permalink
[Plugin] +afterCreatePoolHook
Browse files Browse the repository at this point in the history
  • Loading branch information
fourlen committed May 29, 2024
1 parent af92b9b commit f13c1f2
Show file tree
Hide file tree
Showing 10 changed files with 126 additions and 109 deletions.
2 changes: 2 additions & 0 deletions src/core/contracts/AlgebraFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ contract AlgebraFactory is IAlgebraFactory, Ownable2Step, AccessControlEnumerabl

pool = IAlgebraPoolDeployer(poolDeployer).deploy(plugin, token0, token1, deployer);

defaultPluginFactory.afterCreatePoolHook(plugin);

_poolByPair[token0][token1] = pool;
_poolByPair[token1][token0] = pool;

Expand Down
3 changes: 2 additions & 1 deletion src/farming/contracts/FarmingCenter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import '@cryptoalgebra/integral-periphery/contracts/interfaces/INonfungiblePosit
import '@cryptoalgebra/integral-periphery/contracts/base/Multicall.sol';
import '@cryptoalgebra/integral-periphery/contracts/libraries/PoolAddress.sol';
import '@cryptoalgebra/integral-base-plugin/contracts/interfaces/plugins/IFarmingPlugin.sol';
import '@cryptoalgebra/integral-base-plugin/contracts/modules/FarmingModule.sol';

import './interfaces/IFarmingCenter.sol';
import './libraries/IncentiveId.sol';
Expand Down Expand Up @@ -139,7 +140,7 @@ contract FarmingCenter is IFarmingCenter, IPositionFollower, Multicall {
function _checkParamsForVirtualPoolToggle(address virtualPool, IFarmingPlugin plugin) internal view returns (IAlgebraPool pool) {
require(msg.sender == address(eternalFarming), 'Only farming can call this');
require(virtualPool != address(0), 'Zero address as virtual pool');
pool = IAlgebraPool(plugin.pool());
pool = IAlgebraPool(FarmingModule(address(plugin)).pool());
require(address(pool) == PoolAddress.computeAddress(algebraPoolDeployer, PoolAddress.PoolKey(pool.token0(), pool.token1())), 'Invalid pool');
}
}
51 changes: 39 additions & 12 deletions src/farming/test/shared/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import { ethers } from 'hardhat';

import AlgebraPool from '@cryptoalgebra/integral-core/artifacts/contracts/AlgebraPool.sol/AlgebraPool.json';
import AlgebraFactoryJson from '@cryptoalgebra/integral-core/artifacts/contracts/AlgebraFactory.sol/AlgebraFactory.json';
import DynamicFeeModuleFactoryJson from '@cryptoalgebra/integral-base-plugin/artifacts/contracts/modules/DynamicFeeModuleFactory.sol/DynamicFeeModuleFactory.json';
import FarmingModuleFactoryJson from '@cryptoalgebra/integral-base-plugin/artifacts/contracts/modules/FarmingModuleFactory.sol/FarmingModuleFactory.json';
import OracleModuleFactoryJson from '@cryptoalgebra/integral-base-plugin/artifacts/contracts/modules/OracleModuleFactory.sol/OracleModuleFactory.json';
import AlgebraPoolDeployerJson from '@cryptoalgebra/integral-core/artifacts/contracts/AlgebraPoolDeployer.sol/AlgebraPoolDeployer.json';
import NFTDescriptorJson from '@cryptoalgebra/integral-periphery/artifacts/contracts/libraries/NFTDescriptor.sol/NFTDescriptor.json';
import NonfungiblePositionManagerJson from '@cryptoalgebra/integral-periphery/artifacts/contracts/NonfungiblePositionManager.sol/NonfungiblePositionManager.json';
Expand All @@ -19,7 +22,7 @@ import {
import {
abi as PLUGIN_ABI,
bytecode as PLUGIN_BYTECODE,
} from '@cryptoalgebra/integral-base-plugin/artifacts/contracts/AlgebraBasePluginV1.sol/AlgebraBasePluginV1.json';
} from '@cryptoalgebra/algebra-modular-hub-v0.8.20/artifacts/contracts/AlgebraModularHub.sol/AlgebraModularHub.json';
import {
AlgebraEternalFarming,
TestERC20,
Expand All @@ -30,10 +33,12 @@ import {
IAlgebraPool,
TestIncentiveId,
FarmingCenter,
IAlgebraFarmingModuleFactory,
IAlgebraModularHub,
} from '../../typechain';
import { FeeAmount, encodePriceSqrt, MAX_GAS_LIMIT } from '../shared';
import { ActorFixture } from './actors';
import { IBasePluginV1Factory, IAlgebraBasePluginV1 } from '@cryptoalgebra/integral-base-plugin/typechain';
import { IBasePluginV1Factory } from '@cryptoalgebra/integral-base-plugin/typechain';

type WNativeTokenFixture = { wnative: IWNativeToken };

Expand All @@ -48,7 +53,7 @@ export const wnativeFixture: () => Promise<WNativeTokenFixture> = async () => {
return { wnative };
};

const v3CoreFactoryFixture: () => Promise<[IAlgebraFactory, IAlgebraPoolDeployer, IBasePluginV1Factory, Signer]> = async () => {
const v3CoreFactoryFixture: () => Promise<[IAlgebraFactory, IAlgebraPoolDeployer, IBasePluginV1Factory, IAlgebraFarmingModuleFactory, Signer]> = async () => {
const [deployer] = await ethers.getSigners();
// precompute
const poolDeployerAddress = getCreateAddress({
Expand All @@ -62,12 +67,21 @@ const v3CoreFactoryFixture: () => Promise<[IAlgebraFactory, IAlgebraPoolDeployer
const poolDeployerFactory = await ethers.getContractFactory(AlgebraPoolDeployerJson.abi, AlgebraPoolDeployerJson.bytecode);
const _deployer = (await poolDeployerFactory.deploy(_factory)) as any as IAlgebraPoolDeployer;

const dynamicFeeModuleFactoryFactory = await ethers.getContractFactory(DynamicFeeModuleFactoryJson.abi, DynamicFeeModuleFactoryJson.bytecode);
const dynamicFeeModuleFactory = await dynamicFeeModuleFactoryFactory.deploy(_factory);

const farmingModuleFactoryFactory = await ethers.getContractFactory(FarmingModuleFactoryJson.abi, DynamicFeeModuleFactoryJson.bytecode);
const farmingModuleFactory = await farmingModuleFactoryFactory.deploy(_factory) as any as IAlgebraFarmingModuleFactory;

const oracleModuleFactoryFactory = await ethers.getContractFactory(OracleModuleFactoryJson.abi, OracleModuleFactoryJson.bytecode);
const oracleModuleFactory = await oracleModuleFactoryFactory.deploy(_factory);

const pluginContractFactory = await ethers.getContractFactory(PLUGIN_FACTORY_ABI, PLUGIN_FACTORY_BYTECODE);
const pluginFactory = (await pluginContractFactory.deploy(_factory)) as any as IBasePluginV1Factory;
const pluginFactory = (await pluginContractFactory.deploy(_factory, [dynamicFeeModuleFactory, farmingModuleFactory, oracleModuleFactory])) as any as IBasePluginV1Factory;

await _factory.setDefaultPluginFactory(pluginFactory);

return [_factory, _deployer, pluginFactory, deployer];
return [_factory, _deployer, pluginFactory, farmingModuleFactory, deployer];
};

export const v3RouterFixture: () => Promise<{
Expand All @@ -76,14 +90,15 @@ export const v3RouterFixture: () => Promise<{
deployer: IAlgebraPoolDeployer;
router: ISwapRouter;
pluginFactory: IBasePluginV1Factory;
farmingModuleFactory: IAlgebraFarmingModuleFactory;
ownerSigner: Signer;
}> = async () => {
const { wnative } = await wnativeFixture();
const [factory, deployer, pluginFactory, ownerSigner] = await v3CoreFactoryFixture();
const [factory, deployer, pluginFactory, farmingModuleFactory, ownerSigner] = await v3CoreFactoryFixture();
const routerFactory = await ethers.getContractFactory(SwapRouter.abi, SwapRouter.bytecode);
const router = (await routerFactory.deploy(factory, wnative, deployer)) as any as ISwapRouter;

return { factory, wnative, deployer, router, pluginFactory, ownerSigner };
return { factory, wnative, deployer, router, pluginFactory, farmingModuleFactory, ownerSigner };
};

const nftDescriptorLibraryFixture: () => Promise<NFTDescriptor> = async () => {
Expand All @@ -99,11 +114,12 @@ type AlgebraFactoryFixture = {
nft: INonfungiblePositionManager;
tokens: [TestERC20, TestERC20, TestERC20, TestERC20];
pluginFactory: IBasePluginV1Factory;
farmingModuleFactory: IAlgebraFarmingModuleFactory;
ownerSigner: Signer;
};

export const algebraFactoryFixture: () => Promise<AlgebraFactoryFixture> = async () => {
const { wnative, factory, deployer, router, pluginFactory, ownerSigner } = await v3RouterFixture();
const { wnative, factory, deployer, router, pluginFactory, farmingModuleFactory, ownerSigner } = await v3RouterFixture();

const tokenFactory = await ethers.getContractFactory('TestERC20');
const tokens = (await Promise.all([
Expand Down Expand Up @@ -152,6 +168,7 @@ export const algebraFactoryFixture: () => Promise<AlgebraFactoryFixture> = async
tokens,
nft,
pluginFactory,
farmingModuleFactory,
ownerSigner,
};
};
Expand Down Expand Up @@ -226,8 +243,9 @@ export type AlgebraFixtureType = {
pool12: string;
factory: IAlgebraFactory;
poolObj: IAlgebraPool;
pluginObj: IAlgebraBasePluginV1;
pluginObj: IAlgebraModularHub;
pluginFactory: IBasePluginV1Factory;
farmingModuleFactory: IAlgebraFarmingModuleFactory;
router: ISwapRouter;
eternalFarming: AlgebraEternalFarming;
farmingCenter: FarmingCenter;
Expand All @@ -240,7 +258,8 @@ export type AlgebraFixtureType = {
ownerSigner: Signer;
};
export const algebraFixture: () => Promise<AlgebraFixtureType> = async () => {
const { tokens, nft, factory, deployer, router, pluginFactory, ownerSigner } = await algebraFactoryFixture();
const { tokens, nft, factory, deployer, router, pluginFactory, farmingModuleFactory, ownerSigner } = await algebraFactoryFixture();

const wallets = (await ethers.getSigners()) as any as Wallet[];
const signer = new ActorFixture(wallets, ethers.provider).farmingDeployer();

Expand All @@ -261,7 +280,14 @@ export const algebraFixture: () => Promise<AlgebraFixtureType> = async () => {

await (factory as any as IAccessControl).grantRole(incentiveMakerRole, incentiveCreator.address);

await pluginFactory.setFarmingAddress(farmingCenter);
await factory.grantRole(ethers.keccak256(ethers.toUtf8Bytes("POOLS_ADMINISTRATOR")), pluginFactory);
await factory.grantRole(ethers.keccak256(ethers.toUtf8Bytes("ALGEBRA_BASE_PLUGIN_FACTORY_ADMINISTRATOR")), pluginFactory);

console.log(farmingModuleFactory.target);
const farmingAddress = await farmingModuleFactory.farmingAddress();
// console.log( farmingModuleFactory.farmingAddress(), farmingCenter.target);
console.log(farmingAddress);
await farmingModuleFactory.setFarmingAddress(farmingCenter);

const testIncentiveIdFactory = await ethers.getContractFactory('TestIncentiveId', signer);
const testIncentiveId = (await testIncentiveIdFactory.deploy()) as any as TestIncentiveId;
Expand All @@ -284,7 +310,7 @@ export const algebraFixture: () => Promise<AlgebraFixtureType> = async () => {

const pluginContractFactory = new ethers.ContractFactory(PLUGIN_ABI, PLUGIN_BYTECODE, signer);

const pluginObj = pluginContractFactory.attach(await poolObj.connect(signer).plugin()) as any as IAlgebraBasePluginV1;
const pluginObj = pluginContractFactory.attach(await poolObj.connect(signer).plugin()) as any as IAlgebraModularHub;

return {
nft,
Expand All @@ -301,6 +327,7 @@ export const algebraFixture: () => Promise<AlgebraFixtureType> = async () => {
poolObj,
pluginObj,
pluginFactory,
farmingModuleFactory,
token0: tokens[0],
token1: tokens[1],
rewardToken: tokens[2],
Expand Down
31 changes: 24 additions & 7 deletions src/plugin/contracts/BasePluginV1Factory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import './base/AlgebraModuleFactory.sol';
import './libraries/AdaptiveFee.sol';

import '@cryptoalgebra/algebra-modular-hub-v0.8.20/contracts/AlgebraModularHub.sol';
import '@cryptoalgebra/algebra-modular-hub-v0.8.20/contracts/interfaces/IAlgebraModularHub.sol';
import '@cryptoalgebra/integral-core/contracts/interfaces/IAlgebraPool.sol';
import '@cryptoalgebra/integral-core/contracts/libraries/Plugins.sol';

Expand Down Expand Up @@ -47,37 +48,53 @@ contract BasePluginV1Factory is IBasePluginV1Factory {
return _createPlugin(pool);
}

function afterCreatePoolHook(address modularHub) external {
require(msg.sender == algebraFactory);
_insertModules(modularHub);
}

/// @inheritdoc IBasePluginV1Factory
function createPluginForExistingPool(address token0, address token1) external override returns (address) {
function createPluginForExistingPool(address token0, address token1) external override returns (address pluginAddress) {
IAlgebraFactory factory = IAlgebraFactory(algebraFactory);
require(factory.hasRoleOrOwner(factory.POOLS_ADMINISTRATOR_ROLE(), msg.sender));

address pool = factory.poolByPair(token0, token1);
require(pool != address(0), 'Pool not exist');

return _createPlugin(pool);
pluginAddress = _createPlugin(pool);

_insertModules(pluginAddress);
}

function _createPlugin(address pool) internal returns (address) {
require(pluginByPool[pool] == address(0), 'Already created');

AlgebraModularHub modularHub = new AlgebraModularHub(pool, algebraFactory);

IAlgebraPool(pool).setPlugin(address(modularHub));
// IAlgebraPool(pool).setPlugin(address(modularHub));

for (uint256 i = 0; i < factoriesCounter; ++i) {
address moduleFactoryAddress = factoryByIndex[i];
address moduleAddress = IAlgebraModuleFactory(moduleFactoryAddress).deploy(address(modularHub));

uint256 globalModuleIndex = modularHub.registerModule(moduleAddress);
InsertModuleParams[] memory insertModuleParams = IAlgebraModuleFactory(moduleFactoryAddress).getInsertModuleParams(globalModuleIndex);
modularHub.registerModule(moduleAddress);
// InsertModuleParams[] memory insertModuleParams = IAlgebraModuleFactory(moduleFactoryAddress).getInsertModuleParams(globalModuleIndex);

modularHub.insertModulesToHookLists(insertModuleParams);
// modularHub.insertModulesToHookLists(insertModuleParams);
}

IAlgebraPool(pool).setPluginConfig(uint8(Plugins.DYNAMIC_FEE));
// IAlgebraPool(pool).setPluginConfig(uint8(Plugins.DYNAMIC_FEE));

pluginByPool[pool] = address(modularHub);
return address(modularHub);
}

function _insertModules(address modularHub) internal {
for (uint256 i = 0; i < factoriesCounter; ++i) {
address moduleFactoryAddress = factoryByIndex[i];
IAlgebraModularHub(modularHub).insertModulesToHookLists(
IAlgebraModuleFactory(moduleFactoryAddress).getInsertModuleParams(i + 1)
);
}
}
}
4 changes: 2 additions & 2 deletions src/plugin/contracts/modules/DynamicFeeModuleFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@ contract DynamicFeeModuleFactory is AlgebraModuleFactory {
// dynamic fee hooks shoule be called after oracle, so indexInHookList = 1
insertModuleParams[0] = InsertModuleParams({
selector: IAlgebraPlugin.afterInitialize.selector,
indexInHookList: 1,
indexInHookList: 0,
moduleGlobalIndex: moduleGlobalIndex,
useDelegate: false,
useDynamicFee: true
});

insertModuleParams[1] = InsertModuleParams({
selector: IAlgebraPlugin.beforeSwap.selector,
indexInHookList: 1,
indexInHookList: 0,
moduleGlobalIndex: moduleGlobalIndex,
useDelegate: false,
useDynamicFee: true
Expand Down
4 changes: 2 additions & 2 deletions src/plugin/contracts/test/MockTimeDynamicFeeModuleFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,15 @@ contract MockTimeDynamicFeeModuleFactory is AlgebraModuleFactory {
// dynamic fee hooks shoule be called after oracle, so indexInHookList = 1
insertModuleParams[0] = InsertModuleParams({
selector: IAlgebraPlugin.afterInitialize.selector,
indexInHookList: 1,
indexInHookList: 0,
moduleGlobalIndex: moduleGlobalIndex,
useDelegate: false,
useDynamicFee: true
});

insertModuleParams[1] = InsertModuleParams({
selector: IAlgebraPlugin.beforeSwap.selector,
indexInHookList: 1,
indexInHookList: 0,
moduleGlobalIndex: moduleGlobalIndex,
useDelegate: false,
useDynamicFee: true
Expand Down
31 changes: 1 addition & 30 deletions src/plugin/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 3 additions & 4 deletions src/plugin/test/BasePluginV1Factory.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ describe('BasePluginV1Factory', () => {

it('factory can create plugin', async () => {
const pluginFactoryFactory = await ethers.getContractFactory('BasePluginV1Factory');
const pluginFactoryMock = (await pluginFactoryFactory.deploy(mockAlgebraFactory, [mockOracleModuleFactory, mockDynamicFeeModuleFactory, farmingModuleFactory])) as any as BasePluginV1Factory;
const pluginFactoryMock = (await pluginFactoryFactory.deploy(mockAlgebraFactory, [mockDynamicFeeModuleFactory, farmingModuleFactory, mockOracleModuleFactory])) as any as BasePluginV1Factory;

const mockPoolFactory = await ethers.getContractFactory('MockPool');
const mockPool = (await mockPoolFactory.deploy()) as any as MockPool;
Expand All @@ -49,8 +49,7 @@ describe('BasePluginV1Factory', () => {

const pluginMock = (await ethers.getContractFactory('AlgebraModularHub')).attach(pluginAddress) as any as AlgebraModularHub;

// plugin indexing inside modular hub starts from 1
const dynamicFeeModuleAddress = await pluginMock.modules(2);
const dynamicFeeModuleAddress = await pluginMock.modules(1);

const DynamicFeeModule_ethers = await ethers.getContractFactory('DynamicFeeModule');
const dynamicFeeModule = DynamicFeeModule_ethers.attach(dynamicFeeModuleAddress) as any as DynamicFeeModule;
Expand Down Expand Up @@ -93,7 +92,7 @@ describe('BasePluginV1Factory', () => {
const pluginMock = (await ethers.getContractFactory('AlgebraModularHub')).attach(pluginAddress) as any as AlgebraModularHub;

// plugin indexing inside modular hub starts from 1
const dynamicFeeModuleAddress = await pluginMock.modules(2);
const dynamicFeeModuleAddress = await pluginMock.modules(1);

const DynamicFeeModule_ethers = await ethers.getContractFactory('DynamicFeeModule');
const dynamicFeeModule = DynamicFeeModule_ethers.attach(dynamicFeeModuleAddress) as any as DynamicFeeModule;
Expand Down
Loading

0 comments on commit f13c1f2

Please sign in to comment.