Skip to content

Commit

Permalink
Merge pull request #111 from cryptoalgebra/paladin-fixes
Browse files Browse the repository at this point in the history
Paladin fixes
  • Loading branch information
0xVolosnikov committed Feb 12, 2024
2 parents 2be46e8 + 9482a7c commit c7887f3
Show file tree
Hide file tree
Showing 73 changed files with 947 additions and 432 deletions.
6 changes: 3 additions & 3 deletions src/core/contracts/AlgebraCommunityVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import './libraries/SafeTransfer.sol';
import './libraries/FullMath.sol';

import './interfaces/IAlgebraFactory.sol';
import './interfaces/IAlgebraCommunityVault.sol';
import './interfaces/vault/IAlgebraCommunityVault.sol';

/// @title Algebra community fee vault
/// @notice Community fee from pools is sent here, if it is enabled
Expand Down Expand Up @@ -50,8 +50,8 @@ contract AlgebraCommunityVault is IAlgebraCommunityVault {
_;
}

constructor(address _algebraFeeManager) {
(factory, algebraFeeManager) = (msg.sender, _algebraFeeManager);
constructor(address _factory, address _algebraFeeManager) {
(factory, algebraFeeManager) = (_factory, _algebraFeeManager);
}

/// @inheritdoc IAlgebraCommunityVault
Expand Down
34 changes: 26 additions & 8 deletions src/core/contracts/AlgebraFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import './libraries/Constants.sol';

import './interfaces/IAlgebraFactory.sol';
import './interfaces/IAlgebraPoolDeployer.sol';
import './interfaces/vault/IAlgebraVaultFactory.sol';
import './interfaces/plugin/IAlgebraPluginFactory.sol';

import './AlgebraCommunityVault.sol';
Expand All @@ -22,9 +23,6 @@ contract AlgebraFactory is IAlgebraFactory, Ownable2Step, AccessControlEnumerabl
/// @inheritdoc IAlgebraFactory
address public immutable override poolDeployer;

/// @inheritdoc IAlgebraFactory
address public immutable override communityVault;

/// @inheritdoc IAlgebraFactory
uint16 public override defaultCommunityFee;

Expand All @@ -43,17 +41,19 @@ contract AlgebraFactory is IAlgebraFactory, Ownable2Step, AccessControlEnumerabl
/// @inheritdoc IAlgebraFactory
IAlgebraPluginFactory public defaultPluginFactory;

/// @inheritdoc IAlgebraFactory
IAlgebraVaultFactory public vaultFactory;

/// @inheritdoc IAlgebraFactory
mapping(address => mapping(address => address)) public override poolByPair;

/// @inheritdoc IAlgebraFactory
/// @dev keccak256 of AlgebraPool init bytecode. Used to compute pool address deterministically
bytes32 public constant POOL_INIT_CODE_HASH = 0x177d5fbf994f4d130c008797563306f1a168dc689f81b2fa23b4396931014d91;
bytes32 public constant POOL_INIT_CODE_HASH = 0xf96d2474815c32e070cd63233f06af5413efc5dcb430aee4ff18cc29007c562d;

constructor(address _poolDeployer) {
require(_poolDeployer != address(0));
poolDeployer = _poolDeployer;
communityVault = address(new AlgebraCommunityVault(msg.sender));
defaultTickspacing = Constants.INIT_DEFAULT_TICK_SPACING;
defaultFee = Constants.INIT_DEFAULT_FEE;

Expand All @@ -72,8 +72,13 @@ contract AlgebraFactory is IAlgebraFactory, Ownable2Step, AccessControlEnumerabl
}

/// @inheritdoc IAlgebraFactory
function defaultConfigurationForPool() external view override returns (uint16 communityFee, int24 tickSpacing, uint16 fee) {
return (defaultCommunityFee, defaultTickspacing, defaultFee);
function defaultConfigurationForPool(
address pool
) external view override returns (uint16 communityFee, int24 tickSpacing, uint16 fee, address communityVault) {
if (address(vaultFactory) != address(0)) {
communityVault = vaultFactory.getVaultForPool(pool);
}
return (defaultCommunityFee, defaultTickspacing, defaultFee, communityVault);
}

/// @inheritdoc IAlgebraFactory
Expand All @@ -90,20 +95,25 @@ contract AlgebraFactory is IAlgebraFactory, Ownable2Step, AccessControlEnumerabl

address defaultPlugin;
if (address(defaultPluginFactory) != address(0)) {
defaultPlugin = defaultPluginFactory.createPlugin(computePoolAddress(token0, token1));
defaultPlugin = defaultPluginFactory.createPlugin(computePoolAddress(token0, token1), token0, token1);
}

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

poolByPair[token0][token1] = pool; // to avoid future addresses comparison we are populating the mapping twice
poolByPair[token1][token0] = pool;
emit Pool(token0, token1, pool);

if (address(vaultFactory) != address(0)) {
vaultFactory.createVaultForPool(pool);
}
}

/// @inheritdoc IAlgebraFactory
function setDefaultCommunityFee(uint16 newDefaultCommunityFee) external override onlyOwner {
require(newDefaultCommunityFee <= Constants.MAX_COMMUNITY_FEE);
require(defaultCommunityFee != newDefaultCommunityFee);
if (newDefaultCommunityFee != 0) require(address(vaultFactory) != address(0));
defaultCommunityFee = newDefaultCommunityFee;
emit DefaultCommunityFee(newDefaultCommunityFee);
}
Expand Down Expand Up @@ -132,6 +142,14 @@ contract AlgebraFactory is IAlgebraFactory, Ownable2Step, AccessControlEnumerabl
emit DefaultPluginFactory(newDefaultPluginFactory);
}

/// @inheritdoc IAlgebraFactory
function setVaultFactory(address newVaultFactory) external override onlyOwner {
require(newVaultFactory != address(vaultFactory));
if (newVaultFactory == address(0)) require(defaultCommunityFee == 0);
vaultFactory = IAlgebraVaultFactory(newVaultFactory);
emit VaultFactory(newVaultFactory);
}

/// @inheritdoc IAlgebraFactory
function startRenounceOwnership() external override onlyOwner {
require(renounceOwnershipStartTimestamp == 0);
Expand Down
45 changes: 26 additions & 19 deletions src/core/contracts/AlgebraPool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,19 @@ contract AlgebraPool is AlgebraPoolBase, TickStructure, ReentrancyGuard, Positio
IAlgebraPlugin(plugin).beforeInitialize(msg.sender, initialPrice).shouldReturn(IAlgebraPlugin.beforeInitialize.selector);
}

(uint16 _communityFee, int24 _tickSpacing, uint16 _fee) = _getDefaultConfiguration();
tickSpacing = _tickSpacing;
(uint16 _communityFee, int24 _tickSpacing, uint16 _fee, address _communityVault) = _getDefaultConfiguration();

uint8 pluginConfig = globalState.pluginConfig;
globalState.tick = tick;
globalState.lastFee = _fee;
globalState.communityFee = _communityFee;

emit Initialize(initialPrice, tick);
emit TickSpacing(_tickSpacing);
emit CommunityFee(_communityFee);

_setFee(_fee);
_setTickSpacing(_tickSpacing);
_setCommunityFeeVault(_communityVault);
if (_communityFee != 0 && _communityVault == address(0)) revert invalidNewCommunityFee(); // the pool should not accumulate a community fee without a vault
_setCommunityFee(_communityFee);

if (pluginConfig.hasFlag(Plugins.AFTER_INIT_FLAG)) {
IAlgebraPlugin(plugin).afterInitialize(msg.sender, initialPrice, tick).shouldReturn(IAlgebraPlugin.afterInitialize.selector);
Expand Down Expand Up @@ -218,12 +220,12 @@ contract AlgebraPool is AlgebraPoolBase, TickStructure, ReentrancyGuard, Positio

{
// scope to prevent "stack too deep"
(uint256 balance0Before, uint256 balance1Before) = _updateReserves();
uint160 currentPrice;
int24 currentTick;
uint128 currentLiquidity;
uint256 communityFee;
(amount0, amount1, currentPrice, currentTick, currentLiquidity, communityFee) = _calculateSwap(zeroToOne, amountRequired, limitSqrtPrice);
(uint256 balance0Before, uint256 balance1Before) = _updateReserves();
if (zeroToOne) {
unchecked {
if (amount1 < 0) _transfer(token1, recipient, uint256(-amount1)); // amount1 cannot be > 0
Expand Down Expand Up @@ -392,26 +394,26 @@ contract AlgebraPool is AlgebraPoolBase, TickStructure, ReentrancyGuard, Positio
/// @inheritdoc IAlgebraPoolPermissionedActions
function setCommunityFee(uint16 newCommunityFee) external override onlyUnlocked {
_checkIfAdministrator();
if (newCommunityFee > Constants.MAX_COMMUNITY_FEE || newCommunityFee == globalState.communityFee) revert invalidNewCommunityFee();
globalState.communityFee = newCommunityFee;
emit CommunityFee(newCommunityFee);
if (
newCommunityFee > Constants.MAX_COMMUNITY_FEE ||
newCommunityFee == globalState.communityFee ||
(newCommunityFee != 0 && communityVault == address(0))
) revert invalidNewCommunityFee();
_setCommunityFee(newCommunityFee);
}

/// @inheritdoc IAlgebraPoolPermissionedActions
function setTickSpacing(int24 newTickSpacing) external override onlyUnlocked {
_checkIfAdministrator();
if (newTickSpacing <= 0 || newTickSpacing > Constants.MAX_TICK_SPACING || tickSpacing == newTickSpacing) revert invalidNewTickSpacing();
tickSpacing = newTickSpacing;
emit TickSpacing(newTickSpacing);
_setTickSpacing(newTickSpacing);
}

/// @inheritdoc IAlgebraPoolPermissionedActions
function setPlugin(address newPluginAddress) external override onlyUnlocked {
_checkIfAdministrator();
globalState.pluginConfig = 0;
plugin = newPluginAddress;
emit PluginConfig(0);
emit Plugin(newPluginAddress);
_setPluginConfig(0);
_setPlugin(newPluginAddress);
}

/// @inheritdoc IAlgebraPoolPermissionedActions
Expand All @@ -421,8 +423,14 @@ contract AlgebraPool is AlgebraPoolBase, TickStructure, ReentrancyGuard, Positio

if (msg.sender != _plugin) _checkIfAdministrator();

globalState.pluginConfig = newConfig;
emit PluginConfig(newConfig);
_setPluginConfig(newConfig);
}

/// @inheritdoc IAlgebraPoolPermissionedActions
function setCommunityVault(address newCommunityVault) external override onlyUnlocked {
_checkIfAdministrator();
if (newCommunityVault == address(0) && globalState.communityFee != 0) _setCommunityFee(0); // the pool should not accumulate a community fee without a vault
_setCommunityFeeVault(newCommunityVault); // accumulated but not yet sent to the vault community fees once will be sent to the `newCommunityVault` address
}

/// @inheritdoc IAlgebraPoolPermissionedActions
Expand All @@ -436,7 +444,6 @@ contract AlgebraPool is AlgebraPoolBase, TickStructure, ReentrancyGuard, Positio
if (isDynamicFeeEnabled) revert dynamicFeeActive();
_checkIfAdministrator();
}
globalState.lastFee = newFee;
emit Fee(newFee);
_setFee(newFee);
}
}
19 changes: 7 additions & 12 deletions src/core/contracts/AlgebraPoolDeployer.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity =0.8.20;
pragma abicoder v1;

import './interfaces/IAlgebraPoolDeployer.sol';

Expand All @@ -14,22 +15,16 @@ contract AlgebraPoolDeployer is IAlgebraPoolDeployer {
bytes32 private cache1;

address private immutable factory;
address private immutable communityVault;

constructor(address _factory, address _communityVault) {
require(_factory != address(0) && _communityVault != address(0));
(factory, communityVault) = (_factory, _communityVault);
constructor(address _factory) {
require(_factory != address(0));
factory = _factory;
}

/// @inheritdoc IAlgebraPoolDeployer
function getDeployParameters()
external
view
override
returns (address _plugin, address _factory, address _communityVault, address _token0, address _token1)
{
function getDeployParameters() external view override returns (address _plugin, address _factory, address _token0, address _token1) {
(_plugin, _token0, _token1) = _readFromCache();
(_factory, _communityVault) = (factory, communityVault);
_factory = factory;
}

/// @inheritdoc IAlgebraPoolDeployer
Expand All @@ -46,7 +41,7 @@ contract AlgebraPoolDeployer is IAlgebraPoolDeployer {
assembly {
// cache0 = [plugin, token0[0, 96]], cache1 = [token0[0, 64], 0-s x32 , token1]
token0 := and(token0, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) // clean higher bits, just in case
sstore(cache0.slot, or(shr(64, token0), shl(96, and(plugin, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))))
sstore(cache0.slot, or(shr(64, token0), shl(96, plugin)))
sstore(cache1.slot, or(shl(160, token0), and(token1, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)))
}
}
Expand Down
27 changes: 27 additions & 0 deletions src/core/contracts/AlgebraVaultFactoryStub.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity =0.8.20;
pragma abicoder v1;

import './interfaces/vault/IAlgebraVaultFactory.sol';

/// @title Algebra vault factory stub
/// @notice This contract is used to set AlgebraCommunityVault as communityVault in new pools
contract AlgebraVaultFactoryStub is IAlgebraVaultFactory {
/// @notice the address of AlgebraCommunityVault
address public immutable defaultAlgebraCommunityVault;

constructor(address _algebraCommunityVault) {
require(_algebraCommunityVault != address(0));
defaultAlgebraCommunityVault = _algebraCommunityVault;
}

/// @inheritdoc IAlgebraVaultFactory
function getVaultForPool(address) external view override returns (address) {
return defaultAlgebraCommunityVault;
}

/// @inheritdoc IAlgebraVaultFactory
function createVaultForPool(address) external view override returns (address) {
return defaultAlgebraCommunityVault;
}
}
47 changes: 41 additions & 6 deletions src/core/contracts/base/AlgebraPoolBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@ abstract contract AlgebraPoolBase is IAlgebraPool, Timestamp {
address public immutable override token0;
/// @inheritdoc IAlgebraPoolImmutables
address public immutable override token1;
/// @inheritdoc IAlgebraPoolImmutables
address public immutable override communityVault;

// ! IMPORTANT security note: the pool state can be manipulated
// ! external contracts using this data must prevent read-only reentrancy
Expand All @@ -74,6 +72,9 @@ abstract contract AlgebraPoolBase is IAlgebraPool, Timestamp {
/// @inheritdoc IAlgebraPoolState
address public override plugin;

/// @inheritdoc IAlgebraPoolState
address public override communityVault;

/// @inheritdoc IAlgebraPoolState
mapping(int16 => uint256) public override tickTable;

Expand All @@ -94,9 +95,13 @@ abstract contract AlgebraPoolBase is IAlgebraPool, Timestamp {
}

constructor() {
(plugin, factory, communityVault, token0, token1) = _getDeployParameters();
address _plugin;
(_plugin, factory, token0, token1) = _getDeployParameters();
(prevTickGlobal, nextTickGlobal) = (TickMath.MIN_TICK, TickMath.MAX_TICK);
globalState.unlocked = true;
if (_plugin != address(0)) {
_setPlugin(_plugin);
}
}

/// @inheritdoc IAlgebraPoolState
Expand Down Expand Up @@ -139,13 +144,13 @@ abstract contract AlgebraPoolBase is IAlgebraPool, Timestamp {

/// @dev Gets the parameter values ​​for creating the pool. They are not passed in the constructor to make it easier to use create2 opcode
/// Can be overridden in tests
function _getDeployParameters() internal virtual returns (address, address, address, address, address) {
function _getDeployParameters() internal virtual returns (address, address, address, address) {
return IAlgebraPoolDeployer(msg.sender).getDeployParameters();
}

/// @dev Gets the default settings for pool initialization. Can be overridden in tests
function _getDefaultConfiguration() internal virtual returns (uint16, int24, uint16) {
return IAlgebraFactory(factory).defaultConfigurationForPool();
function _getDefaultConfiguration() internal virtual returns (uint16, int24, uint16, address) {
return IAlgebraFactory(factory).defaultConfigurationForPool(address(this));
}

// The main external calls that are used by the pool. Can be overridden in tests
Expand Down Expand Up @@ -181,4 +186,34 @@ abstract contract AlgebraPoolBase is IAlgebraPool, Timestamp {
// This virtual function is implemented in TickStructure and used in Positions
/// @dev Add or remove a pair of ticks to the corresponding data structure
function _addOrRemoveTicks(int24 bottomTick, int24 topTick, bool toggleBottom, bool toggleTop, int24 currentTick, bool remove) internal virtual;

function _setCommunityFee(uint16 _communityFee) internal {
globalState.communityFee = _communityFee;
emit CommunityFee(_communityFee);
}

function _setCommunityFeeVault(address _communityFeeVault) internal {
communityVault = _communityFeeVault;
emit CommunityVault(_communityFeeVault);
}

function _setFee(uint16 _fee) internal {
globalState.lastFee = _fee;
emit Fee(_fee);
}

function _setTickSpacing(int24 _tickSpacing) internal {
tickSpacing = _tickSpacing;
emit TickSpacing(_tickSpacing);
}

function _setPlugin(address _plugin) internal {
plugin = _plugin;
emit Plugin(_plugin);
}

function _setPluginConfig(uint8 _pluginConfig) internal {
globalState.pluginConfig = _pluginConfig;
emit PluginConfig(_pluginConfig);
}
}

0 comments on commit c7887f3

Please sign in to comment.