Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
8b759d1
add basic scenario tests
SergB47 Jan 21, 2026
5d08181
added some tests
SergB47 Feb 2, 2026
7b348a2
add lock to nfpm
IliaAzhel Feb 26, 2026
3edab17
add tests
Lifopam Feb 26, 2026
d4dc877
improve tests
Lifopam Mar 2, 2026
353ef0e
extend pluginConfig to uint16, add afterCross hook and totalSwapFeeAm…
IliaAzhel Mar 5, 2026
1e9d5dd
add some tests, update gas snapshots
IliaAzhel Mar 5, 2026
41b0476
remove default-plugin from farming package.json, add plugin mock, upd…
IliaAzhel Mar 5, 2026
5220145
bump version to 1.3.0
IliaAzhel Mar 5, 2026
5a0ac73
move algebra fee to factory, split community and algebra fees on chan…
IliaAzhel Mar 9, 2026
f545557
add algebra fee tests
IliaAzhel Mar 9, 2026
ac3287f
move algebra fee vars to another slot for gas optimization
IliaAzhel Mar 9, 2026
0f4a987
Merge branch 'feature/algebra-fees' into release/1.3.0-rc
IliaAzhel Mar 10, 2026
ccd2718
move setters logic to AlgebraPoolExtension
IliaAzhel Mar 11, 2026
db400e8
update periphery and farming snapshots
IliaAzhel Mar 11, 2026
0d17fd2
update branches in gh workflows
IliaAzhel Mar 11, 2026
6d35013
update core gas snapshots
IliaAzhel Mar 11, 2026
143a3c4
improve farming tests
Lifopam Mar 29, 2026
dbb72a0
refactor reward distribution tests to use liquidity ratios for calcul…
Lifopam Apr 2, 2026
14f516b
minor farming tests fixes
IliaAzhel Apr 2, 2026
8573c96
normalize line endings to CRLF for merge compatibility with release/1…
IliaAzhel Apr 2, 2026
065f92a
Merge farming-tests into 1.3.0-rc
IliaAzhel Apr 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ name: Checks
on:
push:
branches:
- integral-v1.2.2
- integral-v1.3
pull_request:
branches:
- integral-v1.2.2
- integral-v1.3

jobs:
Codespell:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/echidna_core.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ name: Echidna Core
on:
push:
branches:
- integral-v1.2.2
- integral-v1.3
pull_request:
branches:
- integral-v1.2.2
- integral-v1.3

jobs:
IntegrationInvariants:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/echidna_farming.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ name: Echidna Farming
on:
push:
branches:
- integral-v1.2.2
- integral-v1.3
pull_request:
branches:
- integral-v1.2.2
- integral-v1.3

jobs:
UnitAsserts:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/echidna_periphery.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ name: Echidna Periphery
on:
push:
branches:
- integral-v1.2.2
- integral-v1.3
pull_request:
branches:
- integral-v1.2.2
- integral-v1.3

jobs:
UnitAsserts:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/tests_core.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ name: Autotests Core
on:
push:
branches:
- integral-v1.2.2
- integral-v1.3
pull_request:
branches:
- integral-v1.2.2
- integral-v1.3

jobs:
Autotests:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/tests_farmings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ name: Autotests Farmings
on:
push:
branches:
- integral-v1.2.2
- integral-v1.3
pull_request:
branches:
- integral-v1.2.2
- integral-v1.3

jobs:
Autotests:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/tests_periphery.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ name: Autotests Periphery
on:
push:
branches:
- integral-v1.2.2
- integral-v1.3
pull_request:
branches:
- integral-v1.2.2
- integral-v1.3

jobs:
Autotests:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Previous versions of the protocol have been moved to separate repositories:

## License

Algebra and Algebra Integral smart-contracts is licensed under the Business Source License 1.1 [(BUSL-1.1)](https://github.com/cryptoalgebra/Algebra/blob/integral-v1.2.2/src/core/LICENSE) and the MIT License (MIT). Licenses for smart contracts are specified in SPDX headers.
Algebra and Algebra Integral smart-contracts is licensed under the Business Source License 1.1 [(BUSL-1.1)](https://github.com/cryptoalgebra/Algebra/blob/integral-v1.3/src/core/LICENSE) and the MIT License (MIT). Licenses for smart contracts are specified in SPDX headers.

## Packages

Expand Down
78 changes: 0 additions & 78 deletions package-lock.json

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

113 changes: 17 additions & 96 deletions src/core/contracts/AlgebraCommunityVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@
pragma solidity =0.8.20;

import './libraries/SafeTransfer.sol';
import './libraries/FullMath.sol';

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

/// @title Algebra community fee vault
/// @notice Community fee from pools is sent here, if it is enabled
/// @dev Role system is used to withdraw tokens
/// @dev Version: Algebra Integral 1.2.2
/// @dev Version: Algebra Integral 1.3
contract AlgebraCommunityVault is IAlgebraCommunityVault {
/// @dev The role can be granted in AlgebraFactory
bytes32 public constant COMMUNITY_FEE_WITHDRAWER_ROLE = keccak256('COMMUNITY_FEE_WITHDRAWER');
Expand All @@ -20,86 +19,39 @@ contract AlgebraCommunityVault is IAlgebraCommunityVault {

/// @notice Address to which community fees are sent from vault
address public communityFeeReceiver;
/// @notice The percentage of the protocol fee that Algebra will receive
/// @dev Value in thousandths,i.e. 1e-3
uint16 public algebraFee;
/// @notice Represents whether there is a new Algebra fee proposal or not
bool public hasNewAlgebraFeeProposal;
/// @notice Suggested Algebra fee value
uint16 public proposedNewAlgebraFee;
/// @notice Address of recipient Algebra part of community fee
address public algebraFeeReceiver;
/// @notice Address of Algebra fee manager
address public algebraFeeManager;
address private _pendingAlgebraFeeManager;

uint16 private constant ALGEBRA_FEE_DENOMINATOR = 1000;

modifier onlyAdministrator() {
require(IAlgebraFactory(factory).hasRoleOrOwner(COMMUNITY_FEE_VAULT_ADMINISTRATOR, msg.sender), 'only administrator');
_;
}

modifier onlyWithdrawer() {
require(msg.sender == algebraFeeManager || IAlgebraFactory(factory).hasRoleOrOwner(COMMUNITY_FEE_WITHDRAWER_ROLE, msg.sender), 'only withdrawer');
_;
}

modifier onlyAlgebraFeeManager() {
require(msg.sender == algebraFeeManager, 'only algebra fee manager');
require(IAlgebraFactory(factory).hasRoleOrOwner(COMMUNITY_FEE_WITHDRAWER_ROLE, msg.sender), 'only withdrawer');
_;
}

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

/// @inheritdoc IAlgebraCommunityVault
function withdraw(address token, uint256 amount) external override onlyWithdrawer {
(uint16 _algebraFee, address _algebraFeeReceiver, address _communityFeeReceiver) = _readAndVerifyWithdrawSettings();
_withdraw(token, _communityFeeReceiver, amount, _algebraFee, _algebraFeeReceiver);
require(communityFeeReceiver != address(0), 'invalid receiver');
SafeTransfer.safeTransfer(token, communityFeeReceiver, amount);
emit TokensWithdrawal(token, communityFeeReceiver, amount);
}

/// @inheritdoc IAlgebraCommunityVault
function withdrawTokens(WithdrawTokensParams[] calldata params) external override onlyWithdrawer {
address _communityFeeReceiver = communityFeeReceiver;
require(_communityFeeReceiver != address(0), 'invalid receiver');
uint256 paramsLength = params.length;
(uint16 _algebraFee, address _algebraFeeReceiver, address _communityFeeReceiver) = _readAndVerifyWithdrawSettings();

unchecked {
for (uint256 i; i < paramsLength; ++i) _withdraw(params[i].token, _communityFeeReceiver, params[i].amount, _algebraFee, _algebraFeeReceiver);
}
}

function _readAndVerifyWithdrawSettings() private view returns (uint16 _algebraFee, address _algebraFeeReceiver, address _communityFeeReceiver) {
(_algebraFee, _algebraFeeReceiver, _communityFeeReceiver) = (algebraFee, algebraFeeReceiver, communityFeeReceiver);
if (_algebraFee != 0) require(_algebraFeeReceiver != address(0), 'invalid algebra fee receiver');
require(_communityFeeReceiver != address(0), 'invalid receiver');
}

function _withdraw(address token, address to, uint256 amount, uint16 _algebraFee, address _algebraFeeReceiver) private {
uint256 withdrawAmount = amount;
if (_algebraFee != 0) {
uint256 algebraFeeAmount = FullMath.mulDivRoundingUp(withdrawAmount, _algebraFee, ALGEBRA_FEE_DENOMINATOR);
withdrawAmount -= algebraFeeAmount;
SafeTransfer.safeTransfer(token, _algebraFeeReceiver, algebraFeeAmount);
emit AlgebraTokensWithdrawal(token, _algebraFeeReceiver, algebraFeeAmount);
for (uint256 i; i < paramsLength; ++i) {
SafeTransfer.safeTransfer(params[i].token, _communityFeeReceiver, params[i].amount);
emit TokensWithdrawal(params[i].token, _communityFeeReceiver, params[i].amount);
}
}

SafeTransfer.safeTransfer(token, to, withdrawAmount);
emit TokensWithdrawal(token, to, withdrawAmount);
}

// ### algebra factory owner permissioned actions ###

/// @inheritdoc IAlgebraCommunityVault
function acceptAlgebraFeeChangeProposal(uint16 newAlgebraFee) external override onlyAdministrator {
require(hasNewAlgebraFeeProposal, 'not proposed');
require(newAlgebraFee == proposedNewAlgebraFee, 'invalid new fee');

// note that the new value will be used for previously accumulated tokens that have not yet been withdrawn
algebraFee = newAlgebraFee;
(proposedNewAlgebraFee, hasNewAlgebraFeeProposal) = (0, false);
emit AlgebraFee(newAlgebraFee);
}

/// @inheritdoc IAlgebraCommunityVault
Expand All @@ -110,40 +62,9 @@ contract AlgebraCommunityVault is IAlgebraCommunityVault {
emit CommunityFeeReceiver(newCommunityFeeReceiver);
}

// ### algebra fee manager permissioned actions ###

/// @inheritdoc IAlgebraCommunityVault
function transferAlgebraFeeManagerRole(address _newAlgebraFeeManager) external override onlyAlgebraFeeManager {
_pendingAlgebraFeeManager = _newAlgebraFeeManager;
emit PendingAlgebraFeeManager(_newAlgebraFeeManager);
}

/// @inheritdoc IAlgebraCommunityVault
function acceptAlgebraFeeManagerRole() external override {
require(msg.sender == _pendingAlgebraFeeManager);
(_pendingAlgebraFeeManager, algebraFeeManager) = (address(0), msg.sender);
emit AlgebraFeeManager(msg.sender);
}

/// @inheritdoc IAlgebraCommunityVault
function proposeAlgebraFeeChange(uint16 newAlgebraFee) external override onlyAlgebraFeeManager {
require(newAlgebraFee <= ALGEBRA_FEE_DENOMINATOR);
require(newAlgebraFee != proposedNewAlgebraFee && newAlgebraFee != algebraFee);
(proposedNewAlgebraFee, hasNewAlgebraFeeProposal) = (newAlgebraFee, true);
emit AlgebraFeeProposal(newAlgebraFee);
}

/// @inheritdoc IAlgebraCommunityVault
function cancelAlgebraFeeChangeProposal() external override onlyAlgebraFeeManager {
(proposedNewAlgebraFee, hasNewAlgebraFeeProposal) = (0, false);
emit CancelAlgebraFeeProposal();
}

/// @inheritdoc IAlgebraCommunityVault
function changeAlgebraFeeReceiver(address newAlgebraFeeReceiver) external override onlyAlgebraFeeManager {
require(newAlgebraFeeReceiver != address(0));
require(newAlgebraFeeReceiver != algebraFeeReceiver);
algebraFeeReceiver = newAlgebraFeeReceiver;
emit AlgebraFeeReceiver(newAlgebraFeeReceiver);
/// @inheritdoc IAlgebraCommunityVaultFeeHandler
// Can be extended in derived contracts if additional logic is needed
function handleCommunityFee(address, address, uint256, uint256) external override {
// solhint-disable-next-line no-empty-blocks
}
}
Loading
Loading