From 2a0b42939f2b3e09207ea173eef67e34cdb17dca Mon Sep 17 00:00:00 2001 From: teddy Date: Mon, 22 Jul 2024 14:00:23 -0300 Subject: [PATCH] feat: add btt tests for finalize methods (#159) * test: btt tests for bpool.swapExactAmountIn * chore: delete preexisting unit tests * test: small renames from feedback * test: be explicit about untestable code * test: adding skipped test for unreachable condition * test: code wasnt so unreachable after all * refactor: get rid of _setRecord * test: btt tests for bcowpool.verify * chore: delete preexisting unit tests * chore: testcase renaming from review * chore: get rid of _setTokens altogether * test: fuzz all possible valid order.sellAmount values * chore: rename correctOrder -> validOrder * test: btt tests for bpool.finalize * test: btt tests for bcowpool.finalize * chore: remove preexisting unit tests replaced by ones in this pr * fix: feedback from review * refactor: make caller==controller default scenario * fix: reorganize .tree * fix: feedback from review * fix: feedback from review, calling internal method directly --- test/manual-smock/MockBCoWPool.sol | 39 +++++++++++++++ test/unit/BCoWPool.t.sol | 35 ------------- test/unit/BCoWPool/BCoWPool.t.sol | 47 ++++++++++++++++++ test/unit/BCoWPool/BCoWPool.tree | 8 +++ test/unit/BCoWPool/BCoWPoolBase.sol | 28 +++++++++++ test/unit/BPool/BPool.t.sol | 49 +++++++++++++++++++ test/unit/BPool/BPool.tree | 14 ++++++ test/unit/BPool/BPoolBase.sol | 2 - test/unit/BPool/BPool_Bind.t.sol | 27 +++++----- test/unit/BPool/BPool_Bind.tree | 45 +++++++++-------- test/unit/BPool/BPool_ExitPool.t.sol | 2 +- .../BPool/BPool_ExitswapPoolAmountIn.t.sol | 4 +- test/unit/BPool/BPool_Unbind.t.sol | 19 +++---- test/unit/BPool/BPool_Unbind.tree | 37 +++++++------- 14 files changed, 246 insertions(+), 110 deletions(-) create mode 100644 test/unit/BCoWPool/BCoWPool.t.sol create mode 100644 test/unit/BCoWPool/BCoWPool.tree create mode 100644 test/unit/BCoWPool/BCoWPoolBase.sol diff --git a/test/manual-smock/MockBCoWPool.sol b/test/manual-smock/MockBCoWPool.sol index 5ce2c703..c94a6bb1 100644 --- a/test/manual-smock/MockBCoWPool.sol +++ b/test/manual-smock/MockBCoWPool.sol @@ -359,6 +359,45 @@ contract MockBCoWPool is BCoWPool, Test { vm.expectCall(address(this), abi.encodeWithSignature('_pushUnderlying(address,address,uint256)', token, to, amount)); } + function mock_call__pushPoolShare(address to, uint256 amount) public { + vm.mockCall(address(this), abi.encodeWithSignature('_pushPoolShare(address,uint256)', to, amount), abi.encode()); + } + + function _pushPoolShare(address to, uint256 amount) internal override { + (bool _success, bytes memory _data) = + address(this).call(abi.encodeWithSignature('_pushPoolShare(address,uint256)', to, amount)); + + if (_success) return abi.decode(_data, ()); + else return super._pushPoolShare(to, amount); + } + + function call__pushPoolShare(address to, uint256 amount) public { + return _pushPoolShare(to, amount); + } + + function expectCall__pushPoolShare(address to, uint256 amount) public { + vm.expectCall(address(this), abi.encodeWithSignature('_pushPoolShare(address,uint256)', to, amount)); + } + + function mock_call__mintPoolShare(uint256 amount) public { + vm.mockCall(address(this), abi.encodeWithSignature('_mintPoolShare(uint256)', amount), abi.encode()); + } + + function _mintPoolShare(uint256 amount) internal override { + (bool _success, bytes memory _data) = address(this).call(abi.encodeWithSignature('_mintPoolShare(uint256)', amount)); + + if (_success) return abi.decode(_data, ()); + else return super._mintPoolShare(amount); + } + + function call__mintPoolShare(uint256 amount) public { + return _mintPoolShare(amount); + } + + function expectCall__mintPoolShare(uint256 amount) public { + vm.expectCall(address(this), abi.encodeWithSignature('_mintPoolShare(uint256)', amount)); + } + function call__afterFinalize() public { return _afterFinalize(); } diff --git a/test/unit/BCoWPool.t.sol b/test/unit/BCoWPool.t.sol index 0a73ea41..08b6673b 100644 --- a/test/unit/BCoWPool.t.sol +++ b/test/unit/BCoWPool.t.sol @@ -78,41 +78,6 @@ contract BCoWPool_Unit_Constructor is BaseCoWPoolTest { } } -contract BCoWPool_Unit_Finalize is BaseCoWPoolTest { - function setUp() public virtual override { - super.setUp(); - - for (uint256 i = 0; i < TOKENS_AMOUNT; i++) { - vm.mockCall(tokens[i], abi.encodePacked(IERC20.approve.selector), abi.encode(true)); - } - - vm.mockCall(address(bCoWPool.FACTORY()), abi.encodeWithSelector(IBCoWFactory.logBCoWPool.selector), abi.encode()); - } - - function test_Set_Approvals() public { - for (uint256 i = 0; i < TOKENS_AMOUNT; i++) { - vm.expectCall(tokens[i], abi.encodeCall(IERC20.approve, (vaultRelayer, type(uint256).max)), 1); - } - bCoWPool.finalize(); - } - - function test_Log_IfRevert() public { - vm.mockCallRevert( - address(bCoWPool.FACTORY()), abi.encodeWithSelector(IBCoWFactory.logBCoWPool.selector), abi.encode() - ); - - vm.expectEmit(address(bCoWPool)); - emit IBCoWFactory.COWAMMPoolCreated(address(bCoWPool)); - - bCoWPool.finalize(); - } - - function test_Call_LogBCoWPool() public { - vm.expectCall(address(bCoWPool.FACTORY()), abi.encodeWithSelector(IBCoWFactory.logBCoWPool.selector), 1); - bCoWPool.finalize(); - } -} - contract BCoWPool_Unit_Commit is BaseCoWPoolTest { function test_Revert_NonSolutionSettler(address sender, bytes32 orderHash) public { vm.assume(sender != cowSolutionSettler); diff --git a/test/unit/BCoWPool/BCoWPool.t.sol b/test/unit/BCoWPool/BCoWPool.t.sol new file mode 100644 index 00000000..b596a622 --- /dev/null +++ b/test/unit/BCoWPool/BCoWPool.t.sol @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.25; + +import {IERC20} from '@cowprotocol/interfaces/IERC20.sol'; + +import {BCoWPoolBase} from './BCoWPoolBase.sol'; + +import {IBCoWFactory} from 'interfaces/IBCoWFactory.sol'; +import {IBPool} from 'interfaces/IBPool.sol'; + +contract BCoWPool_afterFinalize is BCoWPoolBase { + uint256 public tokenWeight = 1e18; + + function setUp() public virtual override { + super.setUp(); + bCoWPool.set__tokens(tokens); + bCoWPool.set__records(tokens[0], IBPool.Record({bound: true, index: 0, denorm: tokenWeight})); + bCoWPool.set__records(tokens[1], IBPool.Record({bound: true, index: 1, denorm: tokenWeight})); + + vm.mockCall(address(this), abi.encodeCall(IBCoWFactory.logBCoWPool, ()), abi.encode()); + + vm.mockCall(tokens[0], abi.encodeCall(IERC20.approve, (vaultRelayer, type(uint256).max)), abi.encode(true)); + vm.mockCall(tokens[1], abi.encodeCall(IERC20.approve, (vaultRelayer, type(uint256).max)), abi.encode(true)); + } + + function test_WhenCalled() external { + // it calls approve on every bound token + vm.expectCall(tokens[0], abi.encodeCall(IERC20.approve, (vaultRelayer, type(uint256).max))); + vm.expectCall(tokens[1], abi.encodeCall(IERC20.approve, (vaultRelayer, type(uint256).max))); + // it calls logBCoWPool on the factory + vm.expectCall(address(this), abi.encodeCall(IBCoWFactory.logBCoWPool, ())); + bCoWPool.call__afterFinalize(); + } + + function test_WhenFactorysLogBCoWPoolDoesNotRevert() external { + // it returns + bCoWPool.call__afterFinalize(); + } + + function test_WhenFactorysLogBCoWPoolReverts(bytes memory revertData) external { + vm.mockCallRevert(address(this), abi.encodeCall(IBCoWFactory.logBCoWPool, ()), revertData); + // it emits a COWAMMPoolCreated event + vm.expectEmit(address(bCoWPool)); + emit IBCoWFactory.COWAMMPoolCreated(address(bCoWPool)); + bCoWPool.call__afterFinalize(); + } +} diff --git a/test/unit/BCoWPool/BCoWPool.tree b/test/unit/BCoWPool/BCoWPool.tree new file mode 100644 index 00000000..0dbbd1f0 --- /dev/null +++ b/test/unit/BCoWPool/BCoWPool.tree @@ -0,0 +1,8 @@ +BCoWPool::_afterFinalize +├── when called +│ ├── it calls approve on every bound token +│ └── it calls logBCoWPool on the factory +├── when factorys logBCoWPool does not revert +│ └── it returns +└── when factorys logBCoWPool reverts + └── it emits a COWAMMPoolCreated event diff --git a/test/unit/BCoWPool/BCoWPoolBase.sol b/test/unit/BCoWPool/BCoWPoolBase.sol new file mode 100644 index 00000000..3418e59e --- /dev/null +++ b/test/unit/BCoWPool/BCoWPoolBase.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.25; + +import {BPoolBase} from '../BPool/BPoolBase.sol'; +import {BCoWConst} from 'contracts/BCoWConst.sol'; +import {BNum} from 'contracts/BNum.sol'; + +import {ISettlement} from 'interfaces/ISettlement.sol'; +import {MockBCoWPool} from 'test/manual-smock/MockBCoWPool.sol'; + +contract BCoWPoolBase is BPoolBase, BCoWConst, BNum { + bytes32 public appData = bytes32('appData'); + address public cowSolutionSettler = makeAddr('cowSolutionSettler'); + bytes32 public domainSeparator = bytes32(bytes2(0xf00b)); + address public vaultRelayer = makeAddr('vaultRelayer'); + address public tokenIn; + address public tokenOut; + MockBCoWPool bCoWPool; + + function setUp() public virtual override { + super.setUp(); + tokenIn = tokens[0]; + tokenOut = tokens[1]; + vm.mockCall(cowSolutionSettler, abi.encodePacked(ISettlement.domainSeparator.selector), abi.encode(domainSeparator)); + vm.mockCall(cowSolutionSettler, abi.encodePacked(ISettlement.vaultRelayer.selector), abi.encode(vaultRelayer)); + bCoWPool = new MockBCoWPool(cowSolutionSettler, appData); + } +} diff --git a/test/unit/BPool/BPool.t.sol b/test/unit/BPool/BPool.t.sol index 264fef02..6bf2db80 100644 --- a/test/unit/BPool/BPool.t.sol +++ b/test/unit/BPool/BPool.t.sol @@ -6,6 +6,8 @@ import {IBPool} from 'interfaces/IBPool.sol'; import {MockBPool} from 'test/smock/MockBPool.sol'; contract BPool is BPoolBase { + uint256 public tokenWeight = 1e18; + function test_ConstructorWhenCalled(address _deployer) external { vm.prank(_deployer); MockBPool _newBPool = new MockBPool(); @@ -50,4 +52,51 @@ contract BPool is BPoolBase { // it returns number of tokens assertEq(bPool.getNumTokens(), _tokensToAdd); } + + function test_FinalizeRevertWhen_CallerIsNotController(address _caller) external { + vm.assume(_caller != address(this)); + vm.prank(_caller); + // it should revert + vm.expectRevert(IBPool.BPool_CallerIsNotController.selector); + bPool.finalize(); + } + + function test_FinalizeRevertWhen_PoolIsFinalized() external { + bPool.set__finalized(true); + // it should revert + vm.expectRevert(IBPool.BPool_PoolIsFinalized.selector); + bPool.finalize(); + } + + function test_FinalizeRevertWhen_ThereAreTooFewTokensBound() external { + address[] memory tokens_ = new address[](1); + tokens_[0] = tokens[0]; + bPool.set__tokens(tokens_); + // it should revert + vm.expectRevert(IBPool.BPool_TokensBelowMinimum.selector); + bPool.finalize(); + } + + function test_FinalizeWhenPreconditionsAreMet() external { + bPool.set__tokens(tokens); + bPool.set__records(tokens[0], IBPool.Record({bound: true, index: 0, denorm: tokenWeight})); + bPool.set__records(tokens[1], IBPool.Record({bound: true, index: 1, denorm: tokenWeight})); + bPool.mock_call__mintPoolShare(INIT_POOL_SUPPLY); + bPool.mock_call__pushPoolShare(address(this), INIT_POOL_SUPPLY); + + // it calls _afterFinalize hook + bPool.expectCall__afterFinalize(); + // it mints initial pool shares + bPool.expectCall__mintPoolShare(INIT_POOL_SUPPLY); + // it sends initial pool shares to controller + bPool.expectCall__pushPoolShare(address(this), INIT_POOL_SUPPLY); + // it emits a LOG_CALL event + bytes memory data = abi.encodeCall(IBPool.finalize, ()); + vm.expectEmit(address(bPool)); + emit IBPool.LOG_CALL(IBPool.finalize.selector, address(this), data); + + bPool.finalize(); + // it finalizes the pool + assertEq(bPool.call__finalized(), true); + } } diff --git a/test/unit/BPool/BPool.tree b/test/unit/BPool/BPool.tree index 379bec03..1f8f368e 100644 --- a/test/unit/BPool/BPool.tree +++ b/test/unit/BPool/BPool.tree @@ -20,3 +20,17 @@ BPool::isBound BPool::getNumTokens └── when called └── it returns number of tokens + +BPool::finalize +├── when caller is not controller +│ └── it should revert +├── when pool is finalized +│ └── it should revert +├── when there are too few tokens bound +│ └── it should revert +└── when preconditions are met + ├── it emits LOG_CALL event + ├── it finalizes the pool + ├── it mints initial pool shares + ├── it sends initial pool shares to controller + └── it calls _afterFinalize hook diff --git a/test/unit/BPool/BPoolBase.sol b/test/unit/BPool/BPoolBase.sol index 36851e2c..092d8147 100644 --- a/test/unit/BPool/BPoolBase.sol +++ b/test/unit/BPool/BPoolBase.sol @@ -9,10 +9,8 @@ import {Utils} from 'test/utils/Utils.sol'; contract BPoolBase is Test, BConst, Utils { MockBPool public bPool; - address public deployer = makeAddr('deployer'); function setUp() public virtual { - vm.prank(deployer); bPool = new MockBPool(); tokens.push(makeAddr('token0')); tokens.push(makeAddr('token1')); diff --git a/test/unit/BPool/BPool_Bind.t.sol b/test/unit/BPool/BPool_Bind.t.sol index c811dfb2..12fb07a4 100644 --- a/test/unit/BPool/BPool_Bind.t.sol +++ b/test/unit/BPool/BPool_Bind.t.sol @@ -26,76 +26,71 @@ contract BPoolBind is BPoolBase { function test_RevertWhen_CallerIsNOTController(address _caller) external { // it should revert - vm.assume(_caller != deployer); + vm.assume(_caller != address(this)); vm.prank(_caller); vm.expectRevert(IBPool.BPool_CallerIsNotController.selector); bPool.bind(tokens[0], tokenBindBalance, tokenWeight); } - modifier whenCallerIsController() { - vm.startPrank(deployer); - _; - } - - function test_RevertWhen_TokenIsAlreadyBound() external whenCallerIsController { + function test_RevertWhen_TokenIsAlreadyBound() external { bPool.set__records(tokens[0], IBPool.Record({bound: true, index: 0, denorm: tokenWeight})); // it should revert vm.expectRevert(IBPool.BPool_TokenAlreadyBound.selector); bPool.bind(tokens[0], tokenBindBalance, tokenWeight); } - function test_RevertWhen_PoolIsFinalized() external whenCallerIsController { + function test_RevertWhen_PoolIsFinalized() external { bPool.set__finalized(true); // it should revert vm.expectRevert(IBPool.BPool_PoolIsFinalized.selector); bPool.bind(tokens[0], tokenBindBalance, tokenWeight); } - function test_RevertWhen_MAX_BOUND_TOKENSTokensAreAlreadyBound() external whenCallerIsController { + function test_RevertWhen_MAX_BOUND_TOKENSTokensAreAlreadyBound() external { _setRandomTokens(MAX_BOUND_TOKENS); // it should revert vm.expectRevert(IBPool.BPool_TokensAboveMaximum.selector); bPool.bind(tokens[0], tokenBindBalance, tokenWeight); } - function test_RevertWhen_TokenWeightIsTooLow() external whenCallerIsController { + function test_RevertWhen_TokenWeightIsTooLow() external { // it should revert vm.expectRevert(IBPool.BPool_WeightBelowMinimum.selector); bPool.bind(tokens[0], tokenBindBalance, MIN_WEIGHT - 1); } - function test_RevertWhen_TokenWeightIsTooHigh() external whenCallerIsController { + function test_RevertWhen_TokenWeightIsTooHigh() external { // it should revert vm.expectRevert(IBPool.BPool_WeightAboveMaximum.selector); bPool.bind(tokens[0], tokenBindBalance, MAX_WEIGHT + 1); } - function test_RevertWhen_TooLittleBalanceIsProvided() external whenCallerIsController { + function test_RevertWhen_TooLittleBalanceIsProvided() external { // it should revert vm.expectRevert(IBPool.BPool_BalanceBelowMinimum.selector); bPool.bind(tokens[0], MIN_BALANCE - 1, tokenWeight); } - function test_RevertWhen_WeightSumExceedsMAX_TOTAL_WEIGHT() external whenCallerIsController { + function test_RevertWhen_WeightSumExceedsMAX_TOTAL_WEIGHT() external { bPool.set__totalWeight(2 * MAX_TOTAL_WEIGHT / 3); // it should revert vm.expectRevert(IBPool.BPool_TotalWeightAboveMaximum.selector); bPool.bind(tokens[0], tokenBindBalance, MAX_TOTAL_WEIGHT / 2); } - function test_WhenTokenCanBeBound(uint256 _existingTokens) external whenCallerIsController { + function test_WhenTokenCanBeBound(uint256 _existingTokens) external { _existingTokens = bound(_existingTokens, 0, MAX_BOUND_TOKENS - 1); bPool.set__tokens(_getDeterministicTokenArray(_existingTokens)); bPool.set__totalWeight(totalWeight); // it calls _pullUnderlying - bPool.expectCall__pullUnderlying(tokens[0], deployer, tokenBindBalance); + bPool.expectCall__pullUnderlying(tokens[0], address(this), tokenBindBalance); // it sets the reentrancy lock bPool.expectCall__setLock(_MUTEX_TAKEN); // it emits LOG_CALL event vm.expectEmit(); bytes memory _data = abi.encodeWithSelector(IBPool.bind.selector, tokens[0], tokenBindBalance, tokenWeight); - emit IBPool.LOG_CALL(IBPool.bind.selector, deployer, _data); + emit IBPool.LOG_CALL(IBPool.bind.selector, address(this), _data); bPool.bind(tokens[0], tokenBindBalance, tokenWeight); diff --git a/test/unit/BPool/BPool_Bind.tree b/test/unit/BPool/BPool_Bind.tree index f0ab3278..a7157745 100644 --- a/test/unit/BPool/BPool_Bind.tree +++ b/test/unit/BPool/BPool_Bind.tree @@ -3,26 +3,25 @@ BPool::Bind │ └── it should revert ├── when caller is NOT controller │ └── it should revert -└── when caller is controller - ├── when token is already bound - │ └── it should revert - ├── when pool is finalized - │ └── it should revert - ├── when MAX_BOUND_TOKENS tokens are already bound - │ └── it should revert - ├── when token weight is too low - │ └── it should revert - ├── when token weight is too high - │ └── it should revert - ├── when too little balance is provided - │ └── it should revert - ├── when weight sum exceeds MAX_TOTAL_WEIGHT - │ └── it should revert - └── when token can be bound - ├── it sets the reentrancy lock - ├── it emits LOG_CALL event - ├── it increments _totalWeight - ├── it calls _pullUnderlying - ├── it adds token to the tokens array - ├── it sets the token record - └── it clears the reentrancy lock +├── when token is already bound +│ └── it should revert +├── when pool is finalized +│ └── it should revert +├── when MAX_BOUND_TOKENS tokens are already bound +│ └── it should revert +├── when token weight is too low +│ └── it should revert +├── when token weight is too high +│ └── it should revert +├── when too little balance is provided +│ └── it should revert +├── when weight sum exceeds MAX_TOTAL_WEIGHT +│ └── it should revert +└── when token can be bound + ├── it sets the reentrancy lock + ├── it emits LOG_CALL event + ├── it increments _totalWeight + ├── it calls _pullUnderlying + ├── it adds token to the tokens array + ├── it sets the token record + └── it clears the reentrancy lock diff --git a/test/unit/BPool/BPool_ExitPool.t.sol b/test/unit/BPool/BPool_ExitPool.t.sol index 858cbef1..11259ba6 100644 --- a/test/unit/BPool/BPool_ExitPool.t.sol +++ b/test/unit/BPool/BPool_ExitPool.t.sol @@ -92,7 +92,7 @@ contract BPoolExitPool is BPoolBase, BNum { // it pulls poolAmountIn shares bPool.expectCall__pullPoolShare(address(this), poolAmountIn); // it sends exitFee to factory - bPool.expectCall__pushPoolShare(deployer, exitFee); + bPool.expectCall__pushPoolShare(address(this), exitFee); // it burns poolAmountIn - exitFee shares bPool.expectCall__burnPoolShare(poolAmountIn - exitFee); // it calls _pushUnderlying for every token diff --git a/test/unit/BPool/BPool_ExitswapPoolAmountIn.t.sol b/test/unit/BPool/BPool_ExitswapPoolAmountIn.t.sol index 8032cdf7..c9ecdff2 100644 --- a/test/unit/BPool/BPool_ExitswapPoolAmountIn.t.sol +++ b/test/unit/BPool/BPool_ExitswapPoolAmountIn.t.sol @@ -32,7 +32,7 @@ contract BPoolExitSwapPoolAmountIn is BPoolBase, BMath { bPool.mock_call__pullPoolShare(address(this), poolAmountIn); bPool.mock_call__burnPoolShare(poolAmountIn); - bPool.mock_call__pushPoolShare(deployer, 0); + bPool.mock_call__pushPoolShare(address(this), 0); bPool.mock_call__pushUnderlying(tokenOut, address(this), expectedAmountOut); } @@ -90,7 +90,7 @@ contract BPoolExitSwapPoolAmountIn is BPoolBase, BMath { // it burns poolAmountIn - exitFee shares bPool.expectCall__burnPoolShare(poolAmountIn); // it sends exitFee to factory - bPool.expectCall__pushPoolShare(deployer, 0); + bPool.expectCall__pushPoolShare(address(this), 0); // it calls _pushUnderlying for token out bPool.expectCall__pushUnderlying(tokenOut, address(this), expectedAmountOut); // it emits LOG_CALL event diff --git a/test/unit/BPool/BPool_Unbind.t.sol b/test/unit/BPool/BPool_Unbind.t.sol index c0c0f008..7034e85c 100644 --- a/test/unit/BPool/BPool_Unbind.t.sol +++ b/test/unit/BPool/BPool_Unbind.t.sol @@ -26,24 +26,19 @@ contract BPoolUnbind is BPoolBase { function test_RevertWhen_CallerIsNOTController(address _caller) external { // it should revert - vm.assume(_caller != deployer); + vm.assume(_caller != address(this)); vm.prank(_caller); vm.expectRevert(IBPool.BPool_CallerIsNotController.selector); bPool.unbind(tokens[0]); } - modifier whenCallerIsController() { - vm.startPrank(deployer); - _; - } - - function test_RevertWhen_TokenIsNotBound() external whenCallerIsController { + function test_RevertWhen_TokenIsNotBound() external { vm.expectRevert(IBPool.BPool_TokenNotBound.selector); // it should revert bPool.unbind(tokens[0]); } - function test_RevertWhen_PoolIsFinalized() external whenCallerIsController { + function test_RevertWhen_PoolIsFinalized() external { bPool.set__records(tokens[0], IBPool.Record({bound: true, index: 0, denorm: 0})); bPool.set__finalized(true); // it should revert @@ -60,16 +55,16 @@ contract BPoolUnbind is BPoolBase { _; } - function test_WhenTokenIsLastOnTheTokensArray() external whenCallerIsController whenTokenCanBeUnbound { + function test_WhenTokenIsLastOnTheTokensArray() external whenTokenCanBeUnbound { // it sets the reentrancy lock bPool.expectCall__setLock(_MUTEX_TAKEN); // it calls _pushUnderlying - bPool.expectCall__pushUnderlying(tokens[0], deployer, boundTokenAmount); + bPool.expectCall__pushUnderlying(tokens[0], address(this), boundTokenAmount); // it emits LOG_CALL event vm.expectEmit(); bytes memory _data = abi.encodeWithSelector(IBPool.unbind.selector, tokens[0]); - emit IBPool.LOG_CALL(IBPool.unbind.selector, deployer, _data); + emit IBPool.LOG_CALL(IBPool.unbind.selector, address(this), _data); bPool.unbind(tokens[0]); // it clears the reentrancy lock @@ -82,7 +77,7 @@ contract BPoolUnbind is BPoolBase { assertEq(bPool.call__totalWeight(), totalWeight - tokenWeight); } - function test_WhenTokenIsNOTLastOnTheTokensArray() external whenCallerIsController whenTokenCanBeUnbound { + function test_WhenTokenIsNOTLastOnTheTokensArray() external whenTokenCanBeUnbound { bPool.set__records(tokens[1], IBPool.Record({bound: true, index: 0, denorm: tokenWeight})); bPool.set__tokens(_tokensToMemory()); bPool.unbind(tokens[0]); diff --git a/test/unit/BPool/BPool_Unbind.tree b/test/unit/BPool/BPool_Unbind.tree index 0f8fd8e7..12ac3f5b 100644 --- a/test/unit/BPool/BPool_Unbind.tree +++ b/test/unit/BPool/BPool_Unbind.tree @@ -3,22 +3,21 @@ BPool::Unbind │ └── it should revert ├── when caller is NOT controller │ └── it should revert -└── when caller is controller - ├── when token is not bound - │ └── it should revert - ├── when pool is finalized - │ └── it should revert - └── when token can be unbound - ├── when token is last on the tokens array - │ ├── it sets the reentrancy lock - │ ├── it emits LOG_CALL event - │ ├── it calls _pushUnderlying - │ ├── it removes the token record - │ ├── it decreases the total weight - │ ├── it pops from the array - │ └── it clears the reentrancy lock - └── when token is NOT last on the tokens array - ├── it removes the token record - ├── it removes the token from the array - ├── it keeps other tokens in the array - └── it updates records to point to the correct indices +├── when token is not bound +│ └── it should revert +├── when pool is finalized +│ └── it should revert +└── when token can be unbound + ├── when token is last on the tokens array + │ ├── it sets the reentrancy lock + │ ├── it emits LOG_CALL event + │ ├── it calls _pushUnderlying + │ ├── it removes the token record + │ ├── it decreases the total weight + │ ├── it pops from the array + │ └── it clears the reentrancy lock + └── when token is NOT last on the tokens array + ├── it removes the token record + ├── it removes the token from the array + ├── it keeps other tokens in the array + └── it updates records to point to the correct indices