Skip to content

Commit

Permalink
+factory
Browse files Browse the repository at this point in the history
  • Loading branch information
fourlen committed May 13, 2024
1 parent 83fd46c commit 762aa94
Show file tree
Hide file tree
Showing 8 changed files with 163 additions and 33 deletions.
21 changes: 19 additions & 2 deletions src/plugin/contracts/AlgebraBasePluginV1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ contract AlgebraBasePluginV1 is IAlgebraBasePluginV1, Timestamp, IAlgebraPlugin
/// @inheritdoc IAlgebraPlugin
uint8 public constant override defaultPluginConfig = uint8(Plugins.AFTER_INIT_FLAG | Plugins.BEFORE_SWAP_FLAG | Plugins.DYNAMIC_FEE);

/// @inheritdoc IFarmingPlugin
address public immutable override pool;
address public immutable pool;
address private immutable factory;
address private immutable pluginFactory;

Expand Down Expand Up @@ -317,4 +316,22 @@ contract AlgebraBasePluginV1 is IAlgebraBasePluginV1, Timestamp, IAlgebraPlugin
IAlgebraPool(pool).setFee(newFee);
}
}

function getCurrentAverageVolatility() external view override returns (uint88) {
uint16 lastIndex = timepointIndex;

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

return timepoints.getAverageVolatility(_blockTimestamp(), tick, lastIndex, oldestIndex);
}

function getAverageVolatilityAtLastTimepoint(
uint32 currentTime,
int24 tick,
uint16 lastIndex,
uint16 oldestIndex
) external view override returns (uint88) {
return timepoints.getAverageVolatility(currentTime, tick, lastIndex, oldestIndex);
}
}
35 changes: 30 additions & 5 deletions src/plugin/contracts/BasePluginV1Factory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ import './interfaces/IBasePluginV1Factory.sol';
import './libraries/AdaptiveFee.sol';
import './AlgebraBasePluginV1.sol';

import './modules/DynamicFeeModule.sol';
import './modules/FarmingModule.sol';
import './modules/OracleModule.sol';

import '@cryptoalgebra/algebra-modular-hub/contracts/AlgebraModularHub.sol';

/// @title Algebra Integral 1.0 default plugin factory
/// @notice This contract creates Algebra default plugins for Algebra liquidity pools
contract BasePluginV1Factory is IBasePluginV1Factory {
Expand All @@ -23,14 +29,23 @@ contract BasePluginV1Factory is IBasePluginV1Factory {
/// @inheritdoc IBasePluginV1Factory
mapping(address poolAddress => address pluginAddress) public override pluginByPool;

address public dynamicFeeModuleFactory;
address public farmingModuleFactory;
address public oracleModuleFactory;

modifier onlyAdministrator() {
require(IAlgebraFactory(algebraFactory).hasRoleOrOwner(ALGEBRA_BASE_PLUGIN_FACTORY_ADMINISTRATOR, msg.sender), 'Only administrator');
_;
}

constructor(address _algebraFactory) {
constructor(address _algebraFactory, address _dynamicFeeModuleFactory, address _farmingModuleFactory, address _oracleModuleFactory) {
algebraFactory = _algebraFactory;
defaultFeeConfiguration = AdaptiveFee.initialFeeConfiguration();

dynamicFeeModuleFactory = _dynamicFeeModuleFactory;
farmingModuleFactory = _farmingModuleFactory;
oracleModuleFactory = _oracleModuleFactory;

emit DefaultFeeConfiguration(defaultFeeConfiguration);
}

Expand All @@ -53,10 +68,20 @@ contract BasePluginV1Factory is IBasePluginV1Factory {

function _createPlugin(address pool) internal returns (address) {
require(pluginByPool[pool] == address(0), 'Already created');
IAlgebraBasePluginV1 volatilityOracle = new AlgebraBasePluginV1(pool, algebraFactory, address(this));
volatilityOracle.changeFeeConfiguration(defaultFeeConfiguration);
pluginByPool[pool] = address(volatilityOracle);
return address(volatilityOracle);
// IAlgebraBasePluginV1 volatilityOracle = new AlgebraBasePluginV1(pool, algebraFactory, address(this));
// volatilityOracle.changeFeeConfiguration(defaultFeeConfiguration);
// pluginByPool[pool] = address(volatilityOracle);
// return address(volatilityOracle);

AlgebraModularHub modularHub = new AlgebraModularHub(pool, algebraFactory);

// address dynamicFeeModule = DynamicFeeModuleFactory(...).deploy(pool);
// address farmingModule = FarmingModuleFactory(...).deploy(pool);
// address oracleModule = OracleModuleFactory(...).deploy(pool);

// modularHub.registerModule(oracleModule);
// modularHub.registerModule(farmingModule);
// modularHub.registerModule(dynamicFeeModule);
}

/// @inheritdoc IBasePluginV1Factory
Expand Down
15 changes: 9 additions & 6 deletions src/plugin/contracts/modules/DynamicFeeModule.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity =0.8.20;
pragma solidity ^0.8.20;

import '@cryptoalgebra/integral-core/contracts/interfaces/pool/IAlgebraPoolState.sol';
import '@cryptoalgebra/integral-core/contracts/interfaces/IAlgebraFactory.sol';
Expand All @@ -19,12 +19,15 @@ import '../libraries/AdaptiveFee.sol';
import '../libraries/VolatilityOracle.sol';

contract DynamicFeeModule is AlgebraModule, IDynamicFeeManager, Timestamp {
string public constant MODULE_NAME = 'Dynamic Fee';

using Plugins for uint8;
using AlgebraFeeConfigurationU144Lib for AlgebraFeeConfiguration;

uint256 internal constant UINT16_MODULO = 65536;
using VolatilityOracle for VolatilityOracle.Timepoint[UINT16_MODULO];

uint8 public constant defaultPluginConfig = uint8(Plugins.AFTER_INIT_FLAG | Plugins.BEFORE_SWAP_FLAG | Plugins.DYNAMIC_FEE);

/// @dev The role can be granted in AlgebraFactory
bytes32 public constant ALGEBRA_BASE_PLUGIN_MANAGER = keccak256('ALGEBRA_BASE_PLUGIN_MANAGER');
Expand Down Expand Up @@ -87,21 +90,21 @@ contract DynamicFeeModule is AlgebraModule, IDynamicFeeManager, Timestamp {
function _afterInitialize(
bytes memory params,
uint16 /* poolFeeCache */
) internal virtual override {
) internal override {
AfterInitializeParams memory decodedParams = abi.decode(params, (AfterInitializeParams));
IAlgebraPool(decodedParams.pool).setFee(_feeConfig.baseFee());
}

function _beforeSwap(
bytes memory params,
uint16 /* poolFeeCache */
) internal virtual override returns (uint16) {
) internal view override {
BeforeSwapParams memory decodedParams = abi.decode(params, (BeforeSwapParams));
uint16 newFee = _getNewFee(decodedParams.pool);
ModuleUtils.returnDynamicFeeResult(newfee, false);
ModuleUtils.returnDynamicFeeResult(newFee, false);
}

function _getNewFee(address pool) internal returns (uint16 newFee) {
function _getNewFee(address pool) internal view returns (uint16 newFee) {
uint16 lastTimepointIndex = IVolatilityOracle(oracleModule).timepointIndex();

uint16 oldestTimepointIndex;
Expand All @@ -115,6 +118,6 @@ contract DynamicFeeModule is AlgebraModule, IDynamicFeeManager, Timestamp {

(, int24 tick, , ) = _getPoolState(pool);

uint16 newFee = _getFeeAtLastTimepoint(lastTimepointIndex, oldestTimepointIndex, tick, _feeConfig);
newFee = _getFeeAtLastTimepoint(lastTimepointIndex, oldestTimepointIndex, tick, _feeConfig);
}
}
39 changes: 39 additions & 0 deletions src/plugin/contracts/modules/DynamicFeeModuleFactory.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.20;

import '../libraries/AdaptiveFee.sol';
import './DynamicFeeModule.sol';


contract DynamicFeeModuleFactory {
event DefaultFeeConfiguration(AlgebraFeeConfiguration newConfig);

bytes32 public constant ALGEBRA_BASE_PLUGIN_FACTORY_ADMINISTRATOR = keccak256('ALGEBRA_BASE_PLUGIN_FACTORY_ADMINISTRATOR');

address public immutable algebraFactory;

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

modifier onlyAdministrator() {
require(IAlgebraFactory(algebraFactory).hasRoleOrOwner(ALGEBRA_BASE_PLUGIN_FACTORY_ADMINISTRATOR, msg.sender), 'Only administrator');
_;
}

constructor(address _algebraFactory) {
algebraFactory = _algebraFactory;
defaultFeeConfiguration = AdaptiveFee.initialFeeConfiguration();
}

function setDefaultFeeConfiguration(AlgebraFeeConfiguration calldata newConfig) external onlyAdministrator {
AdaptiveFee.validateFeeConfiguration(newConfig);
defaultFeeConfiguration = newConfig;
emit DefaultFeeConfiguration(newConfig);
}

function deploy(address oracleModule, address modularHub) external returns (address) {
DynamicFeeModule dynamicFeeModule = new DynamicFeeModule(algebraFactory, address(this), oracleModule, modularHub);
dynamicFeeModule.changeFeeConfiguration(defaultFeeConfiguration);

return address(dynamicFeeModule);
}
}
6 changes: 5 additions & 1 deletion src/plugin/contracts/modules/FarmingModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,12 @@ import '../interfaces/IBasePluginV1Factory.sol';
import '../interfaces/IAlgebraVirtualPool.sol';

contract FarmingModule is AlgebraModule, IFarmingPlugin, Timestamp {
string public constant MODULE_NAME = 'Farming';

using Plugins for uint8;

uint8 public constant defaultPluginConfig = uint8(Plugins.AFTER_SWAP_FLAG);

/// @inheritdoc IFarmingPlugin
address public override incentive;

Expand Down Expand Up @@ -78,7 +82,7 @@ contract FarmingModule is AlgebraModule, IFarmingPlugin, Timestamp {
function _afterSwap(
bytes memory params ,
uint16 /* poolFeeCache */
) internal virtual override {
) internal override {
AfterSwapParams memory decodedParams = abi.decode(params, (AfterSwapParams));

address _incentive = incentive;
Expand Down
16 changes: 9 additions & 7 deletions src/plugin/contracts/modules/OracleModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ import '../interfaces/plugins/IVolatilityOracle.sol';
import '../interfaces/plugins/IDynamicFeeManager.sol';

contract OracleModule is AlgebraModule, IVolatilityOracle, Timestamp {
string public constant MODULE_NAME = 'TWAP Oracle';

using Plugins for uint8;

uint256 internal constant UINT16_MODULO = 65536;
using VolatilityOracle for VolatilityOracle.Timepoint[UINT16_MODULO];

uint8 public constant defaultPluginConfig = uint8(Plugins.AFTER_INIT_FLAG | Plugins.BEFORE_SWAP_FLAG | Plugins.DYNAMIC_FEE);
uint8 public constant defaultPluginConfig = uint8(Plugins.AFTER_INIT_FLAG | Plugins.BEFORE_SWAP_FLAG);

address public immutable modularHub;

Expand Down Expand Up @@ -86,22 +88,22 @@ contract OracleModule is AlgebraModule, IVolatilityOracle, Timestamp {
}
}

function getCurrentAverageVolatility() external view override returns (uint88 volatilityAverage) {
function getCurrentAverageVolatility() external view override returns (uint88) {
uint16 lastIndex = timepointIndex;

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

uint88 volatilityAverage = timepoints.getAverageVolatility(_blockTimestamp(), tick, lastIndex, oldestIndex);
return timepoints.getAverageVolatility(_blockTimestamp(), tick, lastIndex, oldestIndex);
}

function getAverageVolatilityAtLastTimepoint(
uint32 currentTime,
int24 tick,
uint16 lastIndex,
uint16 oldestIndex
) external view override returns (uint88 volatilityAverage) {
uint88 volatilityAverage = timepoints.getAverageVolatility(currentTime, tick, lastIndex, oldestIndex);
) external view override returns (uint88) {
return timepoints.getAverageVolatility(currentTime, tick, lastIndex, oldestIndex);
}

function _getPoolState(address pool) internal view returns (uint160 price, int24 tick, uint16 fee, uint8 pluginConfig) {
Expand All @@ -115,7 +117,7 @@ contract OracleModule is AlgebraModule, IVolatilityOracle, Timestamp {
function _afterInitialize(
bytes memory params,
uint16 /* poolFeeCache */
) internal virtual override {
) internal override {
AfterInitializeParams memory decodedParams = abi.decode(params, (AfterInitializeParams));
uint32 _timestamp = _blockTimestamp();
timepoints.initialize(_timestamp, decodedParams.tick);
Expand All @@ -127,7 +129,7 @@ contract OracleModule is AlgebraModule, IVolatilityOracle, Timestamp {
function _beforeSwap(
bytes memory params,
uint16 /* poolFeeCache */
) internal virtual override {
) internal override {
BeforeSwapParams memory decodedParams = abi.decode(params, (BeforeSwapParams));
_writeTimepoint(decodedParams.pool);
}
Expand Down
13 changes: 13 additions & 0 deletions src/plugin/contracts/test/MockObservable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,17 @@ contract MockVolatilityOracle is IVolatilityOracle {
function getSingleTimepoint(uint32 secondsAgo) external view override returns (int56 tickCumulative, uint88 volatilityCumulative) {}

function prepayTimepointsStorageSlots(uint16 startIndex, uint16 amount) external override {}

function getCurrentAverageVolatility() external view override returns (uint88) {
return 1337;
}

function getAverageVolatilityAtLastTimepoint(
uint32 currentTime,
int24 tick,
uint16 lastIndex,
uint16 oldestIndex
) external view override returns (uint88) {
return 228;
}
}
51 changes: 39 additions & 12 deletions src/plugin/test/shared/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ async function mockFactoryFixture(): Promise<MockFactoryFixture> {
return { mockFactory };
}

// interface PluginFixture extends MockFactoryFixture {
// plugin: MockTimeAlgebraBasePluginV1;
// mockPluginFactory: MockTimeDSFactory;
// mockPool: MockPool;
// }

interface PluginFixture extends MockFactoryFixture {
plugin: MockTimeAlgebraBasePluginV1;
mockPluginFactory: MockTimeDSFactory;
Expand All @@ -26,26 +32,47 @@ export const TEST_POOL_DAY_BEFORE_START = 1601906400 - 24 * 60 * 60;

export const pluginFixture: Fixture<PluginFixture> = async function (): Promise<PluginFixture> {
const { mockFactory } = await mockFactoryFixture();
//const { token0, token1, token2 } = await tokensFixture()

const mockPluginFactoryFactory = await ethers.getContractFactory('MockTimeDSFactory');
const mockPluginFactory = (await mockPluginFactoryFactory.deploy(mockFactory)) as any as MockTimeDSFactory;
const AlgebraModularHub = await ethers.getContractFactory(
"AlgebraModularHub"
);

const mockPoolFactory = await ethers.getContractFactory('MockPool');
const mockPool = (await mockPoolFactory.deploy()) as any as MockPool;

await mockPluginFactory.createPlugin(mockPool, ZERO_ADDRESS, ZERO_ADDRESS);
const pluginAddress = await mockPluginFactory.pluginByPool(mockPool);
const algebraModularHub = await AlgebraModularHub.deploy(
mockPool,
mockFactory
);

const OracleModuleFactory = await ethers.getContractFactory("OracleModule");
const oracleModule = await OracleModuleFactory.deploy(algebraModularHub);

// const { mockFactory } = await mockFactoryFixture();
// //const { token0, token1, token2 } = await tokensFixture()

const mockPluginFactoryFactory = await ethers.getContractFactory('MockTimeDSFactory');
const mockPluginFactory = (await mockPluginFactoryFactory.deploy(mockFactory)) as any as MockTimeDSFactory;

// const mockPoolFactory = await ethers.getContractFactory('MockPool');
// const mockPool = (await mockPoolFactory.deploy()) as any as MockPool;

const mockDSOperatorFactory = await ethers.getContractFactory('MockTimeAlgebraBasePluginV1');
const plugin = mockDSOperatorFactory.attach(pluginAddress) as any as MockTimeAlgebraBasePluginV1;
// await mockPluginFactory.createPlugin(mockPool, ZERO_ADDRESS, ZERO_ADDRESS);
// const pluginAddress = await mockPluginFactory.pluginByPool(mockPool);

// const mockDSOperatorFactory = await ethers.getContractFactory('MockTimeAlgebraBasePluginV1');
// const plugin = mockDSOperatorFactory.attach(pluginAddress) as any as MockTimeAlgebraBasePluginV1;

return {
plugin,
mockPluginFactory,
mockPool,
mockFactory,
};

}

// return {
// plugin,
// mockPluginFactory,
// mockPool,
// mockFactory,
// };
};

interface PluginFactoryFixture extends MockFactoryFixture {
Expand Down

0 comments on commit 762aa94

Please sign in to comment.