From 1287ee622005039aad736b83832782d13894b398 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Thu, 2 May 2024 13:56:29 +0100 Subject: [PATCH 1/7] chore: clean --- foundry.toml | 59 ++++++++++++++++++++++++++++ src/Counter.sol | 14 ------- test/Counter.t.sol | 24 ----------- test/unit/FourSixTwoSixAggBase.t.sol | 26 ++++++++++++ 4 files changed, 85 insertions(+), 38 deletions(-) delete mode 100644 src/Counter.sol delete mode 100644 test/Counter.t.sol create mode 100644 test/unit/FourSixTwoSixAggBase.t.sol diff --git a/foundry.toml b/foundry.toml index 25b918f9..358eeffd 100644 --- a/foundry.toml +++ b/foundry.toml @@ -2,5 +2,64 @@ src = "src" out = "out" libs = ["lib"] +test = 'test' +optimizer = true +optimizer_runs = 20_000 +solc = "0.8.23" +gas_reports = ["*"] +fs_permissions = [{ access = "read", path = "./"}] + +[profile.default.fmt] +line_length = 120 +tab_width = 4 +bracket_spacing = false +int_types = "long" +quote_style = "double" +number_underscore = "preserve" +override_spacing = true + +[profile.fuzz] +runs = 1000 +max_local_rejects = 1024 +max_global_rejects = 65536 +seed = '0x3e8' +dictionary_weight = 100 +include_storage = true +include_push_bytes = true +match_test = "Fuzzing" +match_contract = "Fuzzing" + +[profile.ci_fuzz] +runs = 50000 +max_local_rejects = 1024 +max_global_rejects = 65536 +seed = '0x3e8' +dictionary_weight = 100 +include_storage = true +include_push_bytes = true +match_test = "Fuzzing" +match_contract = "Fuzzing" + +[profile.invariant] +runs = 256 +depth = 15 +fail_on_revert = false +call_override = false +dictionary_weight = 80 +include_storage = true +include_push_bytes = true + +[profile.coverage] +via_ir = true +no_match_test = "Fuzzing" +no_match_contract = "Script" + +[profile.coverage.optimizer_details] +constantOptimizer = true +yul = true + +[profile.coverage.optimizer_details.yulDetails] +stackAllocation = true +optimizerSteps = '' # See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options diff --git a/src/Counter.sol b/src/Counter.sol deleted file mode 100644 index aded7997..00000000 --- a/src/Counter.sol +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.13; - -contract Counter { - uint256 public number; - - function setNumber(uint256 newNumber) public { - number = newNumber; - } - - function increment() public { - number++; - } -} diff --git a/test/Counter.t.sol b/test/Counter.t.sol deleted file mode 100644 index 54b724f7..00000000 --- a/test/Counter.t.sol +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.13; - -import {Test, console} from "forge-std/Test.sol"; -import {Counter} from "../src/Counter.sol"; - -contract CounterTest is Test { - Counter public counter; - - function setUp() public { - counter = new Counter(); - counter.setNumber(0); - } - - function test_Increment() public { - counter.increment(); - assertEq(counter.number(), 1); - } - - function testFuzz_SetNumber(uint256 x) public { - counter.setNumber(x); - assertEq(counter.number(), x); - } -} diff --git a/test/unit/FourSixTwoSixAggBase.t.sol b/test/unit/FourSixTwoSixAggBase.t.sol new file mode 100644 index 00000000..6c4c0190 --- /dev/null +++ b/test/unit/FourSixTwoSixAggBase.t.sol @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +pragma solidity ^0.8.0; + +import {EVaultTestBase} from "../../evault/EVaultTestBase.t.sol"; +import {IEVault, IERC20} from "src/EVault/IEVault.sol"; +import {IRMTestDefault} from "../../../mocks/IRMTestDefault.sol"; +import {ESynth} from "src/Synths/ESynth.sol"; +import {TestERC20} from "../../../mocks/TestERC20.sol"; + +contract ESynthTest is EVaultTestBase { + ESynth esynth; + address user1; + address user2; + + function setUp() public virtual override { + super.setUp(); + + user1 = vm.addr(1001); + user2 = vm.addr(1002); + + esynth = ESynth(address(new ESynth(evc, "Test Synth", "TST"))); + assetTST = TestERC20(address(esynth)); + + eTST = createSynthEVault(address(assetTST)); + } +} \ No newline at end of file From ebe99eacdee5803d37c7303b290ec8aae6724071 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Thu, 2 May 2024 13:59:09 +0100 Subject: [PATCH 2/7] forge install: euler-vault-kit e75770023e1b432a660828120cc166b7dc64a222 --- .gitmodules | 3 +++ lib/euler-vault-kit | 1 + 2 files changed, 4 insertions(+) create mode 160000 lib/euler-vault-kit diff --git a/.gitmodules b/.gitmodules index 2e3aabb7..0e9f83a5 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "lib/ethereum-vault-connector"] path = lib/ethereum-vault-connector url = https://github.com/euler-xyz/ethereum-vault-connector +[submodule "lib/euler-vault-kit"] + path = lib/euler-vault-kit + url = https://github.com/euler-xyz/euler-vault-kit diff --git a/lib/euler-vault-kit b/lib/euler-vault-kit new file mode 160000 index 00000000..e7577002 --- /dev/null +++ b/lib/euler-vault-kit @@ -0,0 +1 @@ +Subproject commit e75770023e1b432a660828120cc166b7dc64a222 From b32c90eee529ae142fc476502f0b2fbc2e0c5f4a Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Thu, 2 May 2024 16:37:41 +0100 Subject: [PATCH 3/7] init FourSixTwoSixAggBase for unit tests --- remappings.txt | 1 + test/unit/FourSixTwoSixAggBase.t.sol | 26 ++++++++++++-------------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/remappings.txt b/remappings.txt index 287f2700..f65498dc 100644 --- a/remappings.txt +++ b/remappings.txt @@ -4,3 +4,4 @@ ethereum-vault-connector/=lib/ethereum-vault-connector/src/ forge-std/=lib/forge-std/src/ openzeppelin-contracts/=lib/ethereum-vault-connector/lib/openzeppelin-contracts/contracts/ openzeppelin/=lib/ethereum-vault-connector/lib/openzeppelin-contracts/contracts/ +evk/=lib/euler-vault-kit/ diff --git a/test/unit/FourSixTwoSixAggBase.t.sol b/test/unit/FourSixTwoSixAggBase.t.sol index 6c4c0190..a7cc1d41 100644 --- a/test/unit/FourSixTwoSixAggBase.t.sol +++ b/test/unit/FourSixTwoSixAggBase.t.sol @@ -1,26 +1,24 @@ // SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.0; -import {EVaultTestBase} from "../../evault/EVaultTestBase.t.sol"; -import {IEVault, IERC20} from "src/EVault/IEVault.sol"; -import {IRMTestDefault} from "../../../mocks/IRMTestDefault.sol"; -import {ESynth} from "src/Synths/ESynth.sol"; -import {TestERC20} from "../../../mocks/TestERC20.sol"; +import {EVaultTestBase, TestERC20} from "evk/test/unit/evault/EVaultTestBase.t.sol"; +import {FourSixTwoSixAgg} from "../../src/FourSixTwoSixAgg.sol"; -contract ESynthTest is EVaultTestBase { - ESynth esynth; +contract FourSixTwoSixAggBase is EVaultTestBase { + address deployer; address user1; address user2; + FourSixTwoSixAgg fourSixTwoSixAgg; + function setUp() public virtual override { super.setUp(); + + deployer = makeAddr("Deployer"); + user1 = makeAddr("User_1"); + user2 = makeAddr("User_2"); - user1 = vm.addr(1001); - user2 = vm.addr(1002); - - esynth = ESynth(address(new ESynth(evc, "Test Synth", "TST"))); - assetTST = TestERC20(address(esynth)); - - eTST = createSynthEVault(address(assetTST)); + vm.prank(deployer); + fourSixTwoSixAgg = new FourSixTwoSixAgg(evc, address(assetTST), "assetTST_Agg", "assetTST_Agg", type(uint120).max, new address[](0), new uint256[](0)); } } \ No newline at end of file From 0b51679440e685d8579a11e0bdd11ba056e039c3 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Thu, 2 May 2024 16:37:55 +0100 Subject: [PATCH 4/7] chore fmt --- src/FourSixTwoSixAgg.sol | 119 ++++++++++++++------------- test/unit/FourSixTwoSixAggBase.t.sol | 14 +++- 2 files changed, 71 insertions(+), 62 deletions(-) diff --git a/src/FourSixTwoSixAgg.sol b/src/FourSixTwoSixAgg.sol index ede8caf7..dbe8ea2c 100644 --- a/src/FourSixTwoSixAgg.sol +++ b/src/FourSixTwoSixAgg.sol @@ -33,7 +33,8 @@ contract FourSixTwoSixAgg is EVCUtil, ERC4626, AccessControlEnumerable { bytes32 public constant ALLOCATION_ADJUSTER_ROLE = keccak256("ALLOCATION_ADJUSTER_ROLE"); bytes32 public constant ALLOCATION_ADJUSTER_ROLE_ADMIN_ROLE = keccak256("ALLOCATION_ADJUSTER_ROLE_ADMIN_ROLE"); bytes32 public constant WITHDRAW_QUEUE_REORDERER_ROLE = keccak256("WITHDRAW_QUEUE_REORDERER_ROLE"); - bytes32 public constant WITHDRAW_QUEUE_REORDERER_ROLE_ADMIN_ROLE = keccak256("WITHDRAW_QUEUE_REORDERER_ROLE_ADMIN_ROLE"); + bytes32 public constant WITHDRAW_QUEUE_REORDERER_ROLE_ADMIN_ROLE = + keccak256("WITHDRAW_QUEUE_REORDERER_ROLE_ADMIN_ROLE"); bytes32 public constant STRATEGY_ADDER_ROLE = keccak256("STRATEGY_ADDER_ROLE"); bytes32 public constant STRATEGY_ADDER_ROLE_ADMIN_ROLE = keccak256("STRATEGY_ADDER_ROLE_ADMIN_ROLE"); bytes32 public constant STRATEGY_REMOVER_ROLE = keccak256("STRATEGY_REMOVER_ROLE"); @@ -87,28 +88,18 @@ contract FourSixTwoSixAgg is EVCUtil, ERC4626, AccessControlEnumerable { uint256 _initialCashAllocationPoints, address[] memory _initialStrategies, uint256[] memory _initialStrategiesAllocationPoints - ) - EVCUtil(address(_evc)) - ERC4626(IERC20(_asset)) - ERC20(_name, _symbol) - { + ) EVCUtil(address(_evc)) ERC4626(IERC20(_asset)) ERC20(_name, _symbol) { esrSlot.locked = REENTRANCYLOCK__UNLOCKED; - if(_initialStrategies.length != _initialStrategiesAllocationPoints.length) revert ArrayLengthMismatch(); - if(_initialCashAllocationPoints == 0) revert InitialAllocationPointsZero(); - - strategies[address(0)] = Strategy({ - allocated: 0, - allocationPoints: uint120(_initialCashAllocationPoints), - active: true - }); - - for(uint256 i; i < _initialStrategies.length; ++i) { - strategies[_initialStrategies[i]] = Strategy({ - allocated: 0, - allocationPoints: uint120(_initialStrategiesAllocationPoints[i]), - active: true - }); + if (_initialStrategies.length != _initialStrategiesAllocationPoints.length) revert ArrayLengthMismatch(); + if (_initialCashAllocationPoints == 0) revert InitialAllocationPointsZero(); + + strategies[address(0)] = + Strategy({allocated: 0, allocationPoints: uint120(_initialCashAllocationPoints), active: true}); + + for (uint256 i; i < _initialStrategies.length; ++i) { + strategies[_initialStrategies[i]] = + Strategy({allocated: 0, allocationPoints: uint120(_initialStrategiesAllocationPoints[i]), active: true}); } // Setup DEFAULT_ADMIN @@ -203,8 +194,8 @@ contract FourSixTwoSixAgg is EVCUtil, ERC4626, AccessControlEnumerable { totalAssetsDeposited -= assets; uint256 assetsRetrieved = IERC20(asset()).balanceOf(address(this)); - for(uint256 i = 0; i < withdrawalQueue.length; i ++) { - if(assetsRetrieved >= assets) { + for (uint256 i = 0; i < withdrawalQueue.length; i++) { + if (assetsRetrieved >= assets) { break; } @@ -217,9 +208,10 @@ contract FourSixTwoSixAgg is EVCUtil, ERC4626, AccessControlEnumerable { uint256 desiredAssets = assets - assetsRetrieved; uint256 withdrawAmount; // We can take all we need 🎉 - if(underlyingBalance > desiredAssets) { + if (underlyingBalance > desiredAssets) { withdrawAmount = desiredAssets; - } else { // not enough but take all we can + } else { + // not enough but take all we can withdrawAmount = underlyingBalance; } @@ -231,7 +223,7 @@ contract FourSixTwoSixAgg is EVCUtil, ERC4626, AccessControlEnumerable { strategy.withdraw(withdrawAmount, address(this), address(this)); } - if(assetsRetrieved < assets) { + if (assetsRetrieved < assets) { revert("Not enough assets to withdraw"); } @@ -267,18 +259,19 @@ contract FourSixTwoSixAgg is EVCUtil, ERC4626, AccessControlEnumerable { return esrSlotCache; } - function rebalance(address strategy) public nonReentrant() { - if(strategy == address(0)) { + function rebalance(address strategy) public nonReentrant { + if (strategy == address(0)) { return; //nothing to rebalance as this is the cash reserve } // Harvest profits, also gulps and updates interest - harvest(strategy); + harvest(strategy); Strategy memory strategyData = strategies[strategy]; uint256 totalAllocationPointsCache = totalAllocationPoints; uint256 totalAssetsAllocatableCache = totalAssetsAllocatable(); - uint256 targetAllocation = totalAssetsAllocatableCache * strategyData.allocationPoints / totalAllocationPointsCache; + uint256 targetAllocation = + totalAssetsAllocatableCache * strategyData.allocationPoints / totalAllocationPointsCache; uint256 currentAllocation = strategyData.allocated; if (currentAllocation > targetAllocation) { @@ -287,17 +280,17 @@ contract FourSixTwoSixAgg is EVCUtil, ERC4626, AccessControlEnumerable { uint256 toWithdraw = currentAllocation - targetAllocation; uint256 maxWithdraw = IERC4626(strategy).maxWithdraw(address(this)); - if(toWithdraw > maxWithdraw) { + if (toWithdraw > maxWithdraw) { toWithdraw = maxWithdraw; } IERC4626(strategy).withdraw(toWithdraw, address(this), address(this)); strategies[strategy].allocated = uint120(targetAllocation); //TODO casting totalAllocated -= toWithdraw; - } - else if (currentAllocation < targetAllocation) { + } else if (currentAllocation < targetAllocation) { // Deposit - uint256 targetCash = totalAssetsAllocatableCache * strategies[address(0)].allocationPoints / totalAllocationPointsCache; + uint256 targetCash = + totalAssetsAllocatableCache * strategies[address(0)].allocationPoints / totalAllocationPointsCache; uint256 currentCash = totalAssetsAllocatableCache - totalAllocated; // Calculate available cash to put in strategies @@ -314,11 +307,11 @@ contract FourSixTwoSixAgg is EVCUtil, ERC4626, AccessControlEnumerable { } uint256 maxDeposit = IERC4626(strategy).maxDeposit(address(this)); - if(toDeposit > maxDeposit) { + if (toDeposit > maxDeposit) { toDeposit = maxDeposit; } - if(toDeposit == 0) { + if (toDeposit == 0) { return; // No cash to deposit } @@ -331,13 +324,13 @@ contract FourSixTwoSixAgg is EVCUtil, ERC4626, AccessControlEnumerable { } // Todo possibly allow batch harvest - function harvest(address strategy) public nonReentrant() { + function harvest(address strategy) public nonReentrant { Strategy memory strategyData = strategies[strategy]; uint256 sharesBalance = IERC4626(strategy).balanceOf(address(this)); uint256 underlyingBalance = IERC4626(strategy).convertToAssets(sharesBalance); - + // There's yield! - if(underlyingBalance > strategyData.allocated) { + if (underlyingBalance > strategyData.allocated) { uint256 yield = underlyingBalance - strategyData.allocated; strategies[strategy].allocated = uint120(underlyingBalance); totalAllocated += yield; @@ -350,30 +343,38 @@ contract FourSixTwoSixAgg is EVCUtil, ERC4626, AccessControlEnumerable { gulp(); } - function adjustAllocationPoints(address strategy, uint256 newPoints) public nonReentrant() onlyRole(ALLOCATION_ADJUSTER_ROLE) { + function adjustAllocationPoints(address strategy, uint256 newPoints) + public + nonReentrant + onlyRole(ALLOCATION_ADJUSTER_ROLE) + { Strategy memory strategyData = strategies[strategy]; uint256 totalAllocationPointsCache = totalAllocationPoints; - if(strategyData.active = false) { + if (strategyData.active = false) { revert("Strategy is inactive"); } strategies[strategy].allocationPoints = uint120(newPoints); - if(newPoints > strategyData.allocationPoints) { + if (newPoints > strategyData.allocationPoints) { uint256 diff = newPoints - strategyData.allocationPoints; totalAllocationPoints + totalAllocationPointsCache + diff; - } else if(newPoints < strategyData.allocationPoints) { + } else if (newPoints < strategyData.allocationPoints) { uint256 diff = strategyData.allocationPoints - newPoints; totalAllocationPoints = totalAllocationPointsCache - diff; } } - function reorderWithdrawalQueue(uint8 index1, uint8 index2) public nonReentrant() onlyRole(WITHDRAW_QUEUE_REORDERER_ROLE) { - if(index1 >= withdrawalQueue.length || index2 >= withdrawalQueue.length) { + function reorderWithdrawalQueue(uint8 index1, uint8 index2) + public + nonReentrant + onlyRole(WITHDRAW_QUEUE_REORDERER_ROLE) + { + if (index1 >= withdrawalQueue.length || index2 >= withdrawalQueue.length) { revert("Index out of bounds"); } - if(index1 == index2) { + if (index1 == index2) { revert("Indexes are the same"); } @@ -382,28 +383,28 @@ contract FourSixTwoSixAgg is EVCUtil, ERC4626, AccessControlEnumerable { withdrawalQueue[index2] = temp; } - function addStrategy(address strategy, uint256 allocationPoints) public nonReentrant() onlyRole(STRATEGY_ADDER_ROLE) { - if(IERC4626(strategy).asset() != asset()) { - revert ("Strategy asset does not match vault asset"); + function addStrategy(address strategy, uint256 allocationPoints) + public + nonReentrant + onlyRole(STRATEGY_ADDER_ROLE) + { + if (IERC4626(strategy).asset() != asset()) { + revert("Strategy asset does not match vault asset"); } - if(strategies[strategy].active) { + if (strategies[strategy].active) { revert("Strategy already exists"); } - strategies[strategy] = Strategy({ - allocated: 0, - allocationPoints: uint120(allocationPoints), - active: true - }); + strategies[strategy] = Strategy({allocated: 0, allocationPoints: uint120(allocationPoints), active: true}); totalAllocationPoints += allocationPoints; withdrawalQueue.push(strategy); } - + // remove strategy, sets its allocation points to zero. Does not pull funds, `harvest` needs to be called to withdraw - function removeStrategy(address strategy) public nonReentrant() onlyRole(STRATEGY_REMOVER_ROLE) { - if(!strategies[strategy].active) { + function removeStrategy(address strategy) public nonReentrant onlyRole(STRATEGY_REMOVER_ROLE) { + if (!strategies[strategy].active) { revert("Strategy is already inactive"); } @@ -447,4 +448,4 @@ contract FourSixTwoSixAgg is EVCUtil, ERC4626, AccessControlEnumerable { function _msgSender() internal view override (Context, EVCUtil) returns (address) { return EVCUtil._msgSender(); } -} \ No newline at end of file +} diff --git a/test/unit/FourSixTwoSixAggBase.t.sol b/test/unit/FourSixTwoSixAggBase.t.sol index a7cc1d41..2a102513 100644 --- a/test/unit/FourSixTwoSixAggBase.t.sol +++ b/test/unit/FourSixTwoSixAggBase.t.sol @@ -13,12 +13,20 @@ contract FourSixTwoSixAggBase is EVaultTestBase { function setUp() public virtual override { super.setUp(); - + deployer = makeAddr("Deployer"); user1 = makeAddr("User_1"); user2 = makeAddr("User_2"); vm.prank(deployer); - fourSixTwoSixAgg = new FourSixTwoSixAgg(evc, address(assetTST), "assetTST_Agg", "assetTST_Agg", type(uint120).max, new address[](0), new uint256[](0)); + fourSixTwoSixAgg = new FourSixTwoSixAgg( + evc, + address(assetTST), + "assetTST_Agg", + "assetTST_Agg", + type(uint120).max, + new address[](0), + new uint256[](0) + ); } -} \ No newline at end of file +} From d25a69499be53f91d3e7026bb978a56655d3a0ef Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Thu, 2 May 2024 16:41:34 +0100 Subject: [PATCH 5/7] update github actions --- .github/workflows/test.yml | 116 +++++++++++++++++++++++++++---------- 1 file changed, 85 insertions(+), 31 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9282e829..1f06d088 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,34 +1,88 @@ -name: test +name: ci -on: workflow_dispatch - -env: - FOUNDRY_PROFILE: ci +on: + push: + branches: + - main + pull_request: jobs: - check: - strategy: - fail-fast: true - - name: Foundry project - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - submodules: recursive - - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - with: - version: nightly - - - name: Run Forge build - run: | - forge --version - forge build --sizes - id: build - - - name: Run Forge tests - run: | - forge test -vvv - id: test + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + submodules: recursive + + - name: Install foundry + uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly + + - name: Run foundry build + run: | + forge --version + forge build + id: build + + lint-check: + runs-on: ubuntu-latest + needs: build + steps: + - uses: actions/checkout@v3 + with: + submodules: recursive + - uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly + + - name: Run foundry fmt check + run: | + forge fmt --check + id: fmt + + test: + runs-on: ubuntu-latest + needs: lint-check + steps: + - uses: actions/checkout@v3 + with: + submodules: recursive + - uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly + - name: Run foundry tests + # --ast tests enables inline configs to work https://github.com/foundry-rs/foundry/issues/7310#issuecomment-1978088200 + run: | + forge test -vv --gas-report --ast + id: test + + fuzz: + runs-on: ubuntu-latest + needs: lint-check + steps: + - uses: actions/checkout@v3 + with: + submodules: recursive + - uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly + - name: Run foundry tests + run: | + FOUNDRY_PROFILE=fuzz forge test -vv + id: fuzz + + coverage: + runs-on: ubuntu-latest + needs: lint-check + steps: + - uses: actions/checkout@v3 + with: + submodules: recursive + - uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly + - name: Run foundry coverage + run: | + FOUNDRY_PROFILE=coverage forge coverage --report summary + id: coverage \ No newline at end of file From 4b0f8e8abfffa5ccfef2d2529ad2f9dcbf327897 Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Thu, 2 May 2024 18:07:35 +0100 Subject: [PATCH 6/7] replace revert messages with custom errors --- src/FourSixTwoSixAgg.sol | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/FourSixTwoSixAgg.sol b/src/FourSixTwoSixAgg.sol index dbe8ea2c..1307e188 100644 --- a/src/FourSixTwoSixAgg.sol +++ b/src/FourSixTwoSixAgg.sol @@ -25,6 +25,14 @@ contract FourSixTwoSixAgg is EVCUtil, ERC4626, AccessControlEnumerable { error AddressesOutOfOrder(); error DuplicateInitialStrategy(); error InitialAllocationPointsZero(); + error NotEnoughAssets(); + error NegativeYield(); + error InactiveStrategy(); + error OutOfBounds(); + error SameIndexes(); + error InvalidStrategyAsset(); + error StrategyAlreadyExist(); + error AlreadyRemoved(); uint8 internal constant REENTRANCYLOCK__UNLOCKED = 1; uint8 internal constant REENTRANCYLOCK__LOCKED = 2; @@ -224,7 +232,7 @@ contract FourSixTwoSixAgg is EVCUtil, ERC4626, AccessControlEnumerable { } if (assetsRetrieved < assets) { - revert("Not enough assets to withdraw"); + revert NotEnoughAssets(); } super._withdraw(caller, receiver, owner, assets, shares); @@ -337,7 +345,7 @@ contract FourSixTwoSixAgg is EVCUtil, ERC4626, AccessControlEnumerable { // TODO possible performance fee } else { // TODO handle losses - revert("For now we panic on negative yield"); + revert NegativeYield(); } gulp(); @@ -352,7 +360,7 @@ contract FourSixTwoSixAgg is EVCUtil, ERC4626, AccessControlEnumerable { uint256 totalAllocationPointsCache = totalAllocationPoints; if (strategyData.active = false) { - revert("Strategy is inactive"); + revert InactiveStrategy(); } strategies[strategy].allocationPoints = uint120(newPoints); @@ -371,11 +379,11 @@ contract FourSixTwoSixAgg is EVCUtil, ERC4626, AccessControlEnumerable { onlyRole(WITHDRAW_QUEUE_REORDERER_ROLE) { if (index1 >= withdrawalQueue.length || index2 >= withdrawalQueue.length) { - revert("Index out of bounds"); + revert OutOfBounds(); } if (index1 == index2) { - revert("Indexes are the same"); + revert SameIndexes(); } address temp = withdrawalQueue[index1]; @@ -389,11 +397,11 @@ contract FourSixTwoSixAgg is EVCUtil, ERC4626, AccessControlEnumerable { onlyRole(STRATEGY_ADDER_ROLE) { if (IERC4626(strategy).asset() != asset()) { - revert("Strategy asset does not match vault asset"); + revert InvalidStrategyAsset(); } if (strategies[strategy].active) { - revert("Strategy already exists"); + revert StrategyAlreadyExist(); } strategies[strategy] = Strategy({allocated: 0, allocationPoints: uint120(allocationPoints), active: true}); @@ -405,7 +413,7 @@ contract FourSixTwoSixAgg is EVCUtil, ERC4626, AccessControlEnumerable { // remove strategy, sets its allocation points to zero. Does not pull funds, `harvest` needs to be called to withdraw function removeStrategy(address strategy) public nonReentrant onlyRole(STRATEGY_REMOVER_ROLE) { if (!strategies[strategy].active) { - revert("Strategy is already inactive"); + revert AlreadyRemoved(); } strategies[strategy].active = false; From de6987076a94a29d74fc77e7da397475f33544fa Mon Sep 17 00:00:00 2001 From: Haythem Sellami <17862704+haythemsellami@users.noreply.github.com> Date: Thu, 2 May 2024 18:12:15 +0100 Subject: [PATCH 7/7] update config --- .github/workflows/test.yml | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1f06d088..e621bc17 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -69,20 +69,20 @@ jobs: version: nightly - name: Run foundry tests run: | - FOUNDRY_PROFILE=fuzz forge test -vv + FOUNDRY_PROFILE=ci_fuzz forge test -vv id: fuzz - coverage: - runs-on: ubuntu-latest - needs: lint-check - steps: - - uses: actions/checkout@v3 - with: - submodules: recursive - - uses: foundry-rs/foundry-toolchain@v1 - with: - version: nightly - - name: Run foundry coverage - run: | - FOUNDRY_PROFILE=coverage forge coverage --report summary - id: coverage \ No newline at end of file + # coverage: + # runs-on: ubuntu-latest + # needs: lint-check + # steps: + # - uses: actions/checkout@v3 + # with: + # submodules: recursive + # - uses: foundry-rs/foundry-toolchain@v1 + # with: + # version: nightly + # - name: Run foundry coverage + # run: | + # FOUNDRY_PROFILE=coverage forge coverage --report summary + # id: coverage \ No newline at end of file