Skip to content

Commit

Permalink
[Plugin] insert module via beforeInitialize hook
Browse files Browse the repository at this point in the history
  • Loading branch information
fourlen committed May 26, 2024
1 parent af92b9b commit 27c3c5a
Show file tree
Hide file tree
Showing 14 changed files with 289 additions and 170 deletions.
25 changes: 21 additions & 4 deletions src/plugin/contracts/BasePluginV1Factory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import './libraries/AdaptiveFee.sol';

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

/// @title Algebra Integral 1.1 default plugin factory
Expand Down Expand Up @@ -63,19 +64,35 @@ contract BasePluginV1Factory is IBasePluginV1Factory {

AlgebraModularHub modularHub = new AlgebraModularHub(pool, algebraFactory);

IAlgebraPool(pool).setPlugin(address(modularHub));
InsertModuleParams[] memory moduleParams = new InsertModuleParams[](factoriesCounter);

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);
// InsertModuleParams[] memory insertModuleParams = IAlgebraModuleFactory(moduleFactoryAddress).getInsertModuleParams(globalModuleIndex);

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

moduleParams[i] = (InsertModuleParams({
selector: IAlgebraPlugin.beforeInitialize.selector,
indexInHookList: i,
moduleGlobalIndex: globalModuleIndex,
useDelegate: true,
useDynamicFee: IAlgebraModuleFactory(moduleFactoryAddress).useDynamicFee()
}));
}

IAlgebraPool(pool).setPluginConfig(uint8(Plugins.DYNAMIC_FEE));
IAlgebraModularHub(modularHub).insertModulesToHookLists(moduleParams);

// struct InsertModuleParams {
// bytes4 selector;
// uint256 indexInHookList;
// uint256 moduleGlobalIndex;
// bool useDelegate;
// bool useDynamicFee;
// }

pluginByPool[pool] = address(modularHub);
return address(modularHub);
Expand Down
6 changes: 4 additions & 2 deletions src/plugin/contracts/interfaces/IAlgebraModuleFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import '@cryptoalgebra/integral-core/contracts/interfaces/IAlgebraFactory.sol';
import '@cryptoalgebra/algebra-modular-hub-v0.8.20/contracts/types/InsertModuleParams.sol';

interface IAlgebraModuleFactory {
function algebraFactory() external returns (address);
function algebraFactory() external view returns (address);

function useDynamicFee() external view returns (bool);

function deploy(address modularHub) external returns (address);

function getInsertModuleParams(uint256 moduleGlobalIndex) external pure returns (InsertModuleParams[] memory);
// function getInsertModuleParams(uint256 moduleGlobalIndex) external pure returns (InsertModuleParams[] memory);
}
30 changes: 30 additions & 0 deletions src/plugin/contracts/modules/DynamicFeeModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import '../interfaces/plugins/IVolatilityOracle.sol';
import '../libraries/AdaptiveFee.sol';
import '../libraries/VolatilityOracle.sol';

import 'hardhat/console.sol';

contract DynamicFeeModule is AlgebraModule, IDynamicFeeManager, Timestamp {
using Plugins for uint8;
using AlgebraFeeConfigurationU144Lib for AlgebraFeeConfiguration;
Expand Down Expand Up @@ -92,6 +94,34 @@ contract DynamicFeeModule is AlgebraModule, IDynamicFeeManager, Timestamp {
(price, tick, fee, pluginConfig, , ) = IAlgebraPoolState(pool).globalState();
}

function _beforeInitialize(
bytes memory /* params */,
uint16 /* poolFeeCache */
) internal override {
console.log('Dynamic fee');

InsertModuleParams[] memory insertModuleParams = new InsertModuleParams[](2);

// dynamic fee hooks shoule be called after oracle, so indexInHookList = 1
insertModuleParams[0] = InsertModuleParams({
selector: IAlgebraPlugin.afterInitialize.selector,
indexInHookList: 1,
moduleGlobalIndex: 2, // ❗❗❗ подумать как сделать получше ❗❗❗
useDelegate: false,
useDynamicFee: true
});

insertModuleParams[1] = InsertModuleParams({
selector: IAlgebraPlugin.beforeSwap.selector,
indexInHookList: 1,
moduleGlobalIndex: 2,
useDelegate: false,
useDynamicFee: true
});

IAlgebraModularHub(modularHub).insertModulesToHookLists(insertModuleParams);
}

function _afterInitialize(
bytes memory /* params */,
uint16 /* poolFeeCache */
Expand Down
47 changes: 25 additions & 22 deletions src/plugin/contracts/modules/DynamicFeeModuleFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import '@cryptoalgebra/integral-core/contracts/interfaces/plugin/IAlgebraPlugin.
contract DynamicFeeModuleFactory is AlgebraModuleFactory {
event DefaultFeeConfiguration(AlgebraFeeConfiguration newConfig);

/// @inheritdoc IAlgebraModuleFactory
bool public override useDynamicFee = true;

AlgebraFeeConfiguration public defaultFeeConfiguration; // values of constants for sigmoids in fee calculation formula

constructor(address _algebraFactory) AlgebraModuleFactory(_algebraFactory) {
Expand All @@ -35,26 +38,26 @@ contract DynamicFeeModuleFactory is AlgebraModuleFactory {
return address(dynamicFeeModule);
}

function getInsertModuleParams(uint256 moduleGlobalIndex) external override pure returns (InsertModuleParams[] memory) {
InsertModuleParams[] memory insertModuleParams = new InsertModuleParams[](2);

// dynamic fee hooks shoule be called after oracle, so indexInHookList = 1
insertModuleParams[0] = InsertModuleParams({
selector: IAlgebraPlugin.afterInitialize.selector,
indexInHookList: 1,
moduleGlobalIndex: moduleGlobalIndex,
useDelegate: false,
useDynamicFee: true
});

insertModuleParams[1] = InsertModuleParams({
selector: IAlgebraPlugin.beforeSwap.selector,
indexInHookList: 1,
moduleGlobalIndex: moduleGlobalIndex,
useDelegate: false,
useDynamicFee: true
});

return insertModuleParams;
}
// function getInsertModuleParams(uint256 moduleGlobalIndex) external override pure returns (InsertModuleParams[] memory) {
// InsertModuleParams[] memory insertModuleParams = new InsertModuleParams[](2);

// // dynamic fee hooks shoule be called after oracle, so indexInHookList = 1
// insertModuleParams[0] = InsertModuleParams({
// selector: IAlgebraPlugin.afterInitialize.selector,
// indexInHookList: 1,
// moduleGlobalIndex: moduleGlobalIndex,
// useDelegate: false,
// useDynamicFee: true
// });

// insertModuleParams[1] = InsertModuleParams({
// selector: IAlgebraPlugin.beforeSwap.selector,
// indexInHookList: 1,
// moduleGlobalIndex: moduleGlobalIndex,
// useDelegate: false,
// useDynamicFee: true
// });

// return insertModuleParams;
// }
}
19 changes: 17 additions & 2 deletions src/plugin/contracts/modules/FarmingModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,27 @@ contract FarmingModule is AlgebraModule, IFarmingPlugin, Timestamp {
(price, tick, fee, pluginConfig, , ) = IAlgebraPoolState(pool).globalState();
}

function _beforeInitialize(
bytes memory /* params */,
uint16 /* poolFeeCache */
) internal override {
InsertModuleParams[] memory insertModuleParams = new InsertModuleParams[](1);

insertModuleParams[0] = InsertModuleParams({
selector: IAlgebraPlugin.afterSwap.selector,
indexInHookList: 0,
moduleGlobalIndex: 3,
useDelegate: false,
useDynamicFee: false
});

IAlgebraModularHub(modularHub).insertModulesToHookLists(insertModuleParams);
}

function _afterSwap(
bytes memory params ,
uint16 /* poolFeeCache */
) internal override {
// console.log("Farming afterInitialize");

AfterSwapParams memory decodedParams = abi.decode(params, (AfterSwapParams));

address _incentive = incentive;
Expand Down
26 changes: 15 additions & 11 deletions src/plugin/contracts/modules/FarmingModuleFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@ import '../base/AlgebraModuleFactory.sol';
import './FarmingModule.sol';

contract FarmingModuleFactory is AlgebraModuleFactory, IAlgebraFarmingModuleFactory {
/// @inheritdoc IAlgebraFarmingModuleFactory
address public override farmingAddress;

/// @inheritdoc IAlgebraModuleFactory
bool public override useDynamicFee = false;

constructor(address _algebraFactory) AlgebraModuleFactory(_algebraFactory) {}

function setFarmingAddress(address newFarmingAddress) external override onlyAdministrator {
Expand All @@ -24,17 +28,17 @@ contract FarmingModuleFactory is AlgebraModuleFactory, IAlgebraFarmingModuleFact
return address(farmingModule);
}

function getInsertModuleParams(uint256 moduleGlobalIndex) external override pure returns (InsertModuleParams[] memory) {
InsertModuleParams[] memory insertModuleParams = new InsertModuleParams[](1);
// function getInsertModuleParams(uint256 moduleGlobalIndex) external override pure returns (InsertModuleParams[] memory) {
// InsertModuleParams[] memory insertModuleParams = new InsertModuleParams[](1);

insertModuleParams[0] = InsertModuleParams({
selector: IAlgebraPlugin.afterSwap.selector,
indexInHookList: 0,
moduleGlobalIndex: moduleGlobalIndex,
useDelegate: false,
useDynamicFee: false
});
// insertModuleParams[0] = InsertModuleParams({
// selector: IAlgebraPlugin.afterSwap.selector,
// indexInHookList: 0,
// moduleGlobalIndex: moduleGlobalIndex,
// useDelegate: false,
// useDynamicFee: false
// });

return insertModuleParams;
}
// return insertModuleParams;
// }
}
47 changes: 36 additions & 11 deletions src/plugin/contracts/modules/OracleModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ contract OracleModule is AlgebraModule, IVolatilityOracle, Timestamp {
function initialize() external {
require(!isInitialized, 'Already initialized');
require(IAlgebraModularHub(modularHub).moduleAddressToIndex(address(this)) != 0, 'Plugin not attached');
(uint160 price, int24 tick, , ) = _getPoolState(pool);
(uint160 price, int24 tick, , ) = _getPoolState();
require(price != 0, 'Pool is not initialized');

uint32 time = _blockTimestamp();
Expand All @@ -57,7 +57,7 @@ contract OracleModule is AlgebraModule, IVolatilityOracle, Timestamp {
/// @inheritdoc IVolatilityOracle
function getSingleTimepoint(uint32 secondsAgo) external view override returns (int56 tickCumulative, uint88 volatilityCumulative) {
// `volatilityCumulative` values for timestamps after the last timepoint _should not_ be compared: they may differ due to interpolation errors
(, int24 tick, , ) = _getPoolState(IAlgebraModularHub(modularHub).pool());
(, int24 tick, , ) = _getPoolState();
uint16 lastTimepointIndex = timepointIndex;
uint16 oldestIndex = timepoints.getOldestIndex(lastTimepointIndex);
VolatilityOracle.Timepoint memory result = timepoints.getSingleTimepoint(_blockTimestamp(), secondsAgo, tick, lastTimepointIndex, oldestIndex);
Expand All @@ -69,7 +69,7 @@ contract OracleModule is AlgebraModule, IVolatilityOracle, Timestamp {
uint32[] memory secondsAgos
) external view override returns (int56[] memory tickCumulatives, uint88[] memory volatilityCumulatives) {
// `volatilityCumulative` values for timestamps after the last timepoint _should not_ be compared: they may differ due to interpolation errors
(, int24 tick, , ) = _getPoolState(IAlgebraModularHub(modularHub).pool());
(, int24 tick, , ) = _getPoolState();
return timepoints.getTimepoints(_blockTimestamp(), secondsAgos, tick, timepointIndex);
}

Expand All @@ -89,7 +89,7 @@ contract OracleModule is AlgebraModule, IVolatilityOracle, Timestamp {
uint16 lastIndex = timepointIndex;

uint16 oldestIndex = timepoints.getOldestIndex(lastIndex);
(, int24 tick, , ) = _getPoolState(IAlgebraModularHub(modularHub).pool());
(, int24 tick, , ) = _getPoolState();

return timepoints.getAverageVolatility(_blockTimestamp(), tick, lastIndex, oldestIndex);
}
Expand All @@ -103,14 +103,40 @@ contract OracleModule is AlgebraModule, IVolatilityOracle, Timestamp {
return timepoints.getAverageVolatility(currentTime, tick, lastIndex, oldestIndex);
}

function _getPoolState(address pool) internal view returns (uint160 price, int24 tick, uint16 fee, uint8 pluginConfig) {
function _getPoolState() internal view returns (uint160 price, int24 tick, uint16 fee, uint8 pluginConfig) {
(price, tick, fee, pluginConfig, , ) = IAlgebraPoolState(pool).globalState();
}

function _getPluginInPool(address pool) internal view returns (address plugin) {
function _getPluginInPool() internal view returns (address plugin) {
return IAlgebraPool(pool).plugin();
}

function _beforeInitialize(
bytes memory /* params */,
uint16 /* poolFeeCache */
) internal override {
InsertModuleParams[] memory insertModuleParams = new InsertModuleParams[](2);

// oracle module must be first, so indexInHookList = 0
insertModuleParams[0] = InsertModuleParams({
selector: IAlgebraPlugin.afterInitialize.selector,
indexInHookList: 0,
moduleGlobalIndex: 1,
useDelegate: false,
useDynamicFee: false
});

insertModuleParams[1] = InsertModuleParams({
selector: IAlgebraPlugin.beforeSwap.selector,
indexInHookList: 0,
moduleGlobalIndex: 1,
useDelegate: false,
useDynamicFee: false
});

IAlgebraModularHub(modularHub).insertModulesToHookLists(insertModuleParams);
}

function _afterInitialize(
bytes memory params,
uint16 /* poolFeeCache */
Expand All @@ -124,14 +150,13 @@ contract OracleModule is AlgebraModule, IVolatilityOracle, Timestamp {
}

function _beforeSwap(
bytes memory params,
bytes memory /* params */,
uint16 /* poolFeeCache */
) internal override {
BeforeSwapParams memory decodedParams = abi.decode(params, (BeforeSwapParams));
_writeTimepoint(decodedParams.pool);
_writeTimepoint();
}

function _writeTimepoint(address pool) internal {
function _writeTimepoint() internal {
// console.log('Write timepoint called');

// single SLOAD
Expand All @@ -145,7 +170,7 @@ contract OracleModule is AlgebraModule, IVolatilityOracle, Timestamp {

if (_lastTimepointTimestamp == currentTimestamp) return;

(, int24 tick, , ) = _getPoolState(pool);
(, int24 tick, , ) = _getPoolState();
// (uint16 newLastIndex, ) = timepoints.write(_lastIndex, currentTimestamp, tick);
(uint16 newLastIndex, ) = timepoints.write(_lastIndex, currentTimestamp, tick);

Expand Down
Loading

0 comments on commit 27c3c5a

Please sign in to comment.