From 8edb50f688f4ebc1a1724679b20b0affc72d889b Mon Sep 17 00:00:00 2001 From: elshan_eth Date: Wed, 18 Dec 2024 20:17:24 +0100 Subject: [PATCH] first iteration --- .../test/foundry/utils/BaseTest.sol | 235 +++++++++++------- pkg/vault/test/foundry/AuxiliaryEvent.t.sol | 8 +- .../test/foundry/BalancerPoolTokenTest.t.sol | 6 +- pkg/vault/test/foundry/BatchRouter.t.sol | 8 +- .../test/foundry/utils/BaseVaultTest.sol | 63 +++-- 5 files changed, 209 insertions(+), 111 deletions(-) diff --git a/pkg/solidity-utils/test/foundry/utils/BaseTest.sol b/pkg/solidity-utils/test/foundry/utils/BaseTest.sol index e6f17fe68..0ec1ca92d 100644 --- a/pkg/solidity-utils/test/foundry/utils/BaseTest.sol +++ b/pkg/solidity-utils/test/foundry/utils/BaseTest.sol @@ -16,57 +16,76 @@ import { ERC4626TestToken } from "../../../contracts/test/ERC4626TestToken.sol"; import { ERC20TestToken } from "../../../contracts/test/ERC20TestToken.sol"; import { WETHTestToken } from "../../../contracts/test/WETHTestToken.sol"; -abstract contract BaseTest is Test, GasSnapshot { - using CastingHelpers for *; - - // Reasonable block.timestamp `MAY_1_2023` - uint32 internal constant START_TIMESTAMP = 1_682_899_200; - - uint256 internal constant MAX_UINT256 = type(uint256).max; - // Raw token balances are stored in half a slot, so the max is uint128. - uint256 internal constant MAX_UINT128 = type(uint128).max; - +struct Accounts { // Default admin. - address payable internal admin; - uint256 internal adminKey; + address payable admin; + uint256 adminKey; // Default liquidity provider. - address payable internal lp; - uint256 internal lpKey; + address payable lp; + uint256 lpKey; // Default user. - address payable internal alice; - uint256 internal aliceKey; + address payable alice; + uint256 aliceKey; // Default counterparty. - address payable internal bob; - uint256 internal bobKey; + address payable bob; + uint256 bobKey; // Malicious user. - address payable internal hacker; - uint256 internal hackerKey; + address payable hacker; + uint256 hackerKey; // Broke user. - address payable internal broke; - uint256 internal brokeUserKey; - + address payable broke; + uint256 brokeUserKey; // List of all users - address payable[] internal users; - uint256[] internal userKeys; + address payable[] users; + uint256[] userKeys; +} +struct TokensInfo { // ERC20 tokens used for tests. - ERC20TestToken internal dai; - ERC20TestToken internal usdc; - WETHTestToken internal weth; - ERC20TestToken internal wsteth; - ERC20TestToken internal veBAL; - ERC4626TestToken internal waDAI; - ERC4626TestToken internal waWETH; - ERC4626TestToken internal waUSDC; - + ERC20TestToken dai; + ERC20TestToken usdc; + WETHTestToken weth; + ERC20TestToken wsteth; + ERC20TestToken veBAL; + ERC4626TestToken waDAI; + ERC4626TestToken waWETH; + ERC4626TestToken waUSDC; // List of all ERC20 tokens - IERC20[] internal tokens; - + IERC20[] tokens; // List of all ERC4626 tokens - IERC4626[] internal erc4626Tokens; + IERC4626[] erc4626Tokens; +} + +struct BaseTestState { + Accounts accounts; + TokensInfo tokensInfo; +} + +abstract contract BaseTest is Test, GasSnapshot { + using CastingHelpers for *; + + // Reasonable block.timestamp `MAY_1_2023` + uint32 internal constant START_TIMESTAMP = 1_682_899_200; + + uint256 internal constant DEFAULT_BALANCE = 1e9 * 1e18; + + uint256 internal constant MAX_UINT256 = type(uint256).max; + // Raw token balances are stored in half a slot, so the max is uint128. + uint256 internal constant MAX_UINT128 = type(uint128).max; // Default balance for accounts - uint256 internal defaultBalance = 1e9 * 1e18; + bool private _initialized; + uint256 private _defaultBalance = DEFAULT_BALANCE; + BaseTestState private _state; + + // -------------------- Initializers -------------------- + function setDefaultBalance(uint256 defaultBalance) internal { + if (_initialized) { + revert("Default balance can only be set before the test is initialized"); + } + + _defaultBalance = defaultBalance; + } function setUp() public virtual { // Set timestamp only if testing locally @@ -76,66 +95,110 @@ abstract contract BaseTest is Test, GasSnapshot { } // Deploy the base test contracts. - dai = createERC20("DAI", 18); + ERC20TestToken dai = createERC20("DAI", 18); // "USDC" is deliberately 18 decimals to test one thing at a time. - usdc = createERC20("USDC", 18); - wsteth = createERC20("WSTETH", 18); - weth = new WETHTestToken(); + ERC20TestToken usdc = createERC20("USDC", 18); + ERC20TestToken wsteth = createERC20("WSTETH", 18); + ERC20TestToken weth = new WETHTestToken(); vm.label(address(weth), "WETH"); - veBAL = createERC20("veBAL", 18); + ERC20TestToken veBAL = createERC20("veBAL", 18); + + _state.tokensInfo.dai = dai; + _state.tokensInfo.usdc = usdc; + _state.tokensInfo.weth = weth; + _state.tokensInfo.wsteth = wsteth; + _state.tokensInfo.veBAL = veBAL; - // Fill the token list. - tokens.push(dai); - tokens.push(usdc); - tokens.push(weth); - tokens.push(wsteth); + _state.tokensInfo.tokens.push(dai); + _state.tokensInfo.tokens.push(usdc); + _state.tokensInfo.tokens.push(weth); + _state.tokensInfo.tokens.push(wsteth); + _state.tokensInfo.tokens.push(veBAL); // Deploy ERC4626 tokens. - waDAI = createERC4626("Wrapped aDAI", "waDAI", 18, dai); - waWETH = createERC4626("Wrapped aWETH", "waWETH", 18, weth); + ERC4626TestToken waDAI = createERC4626("Wrapped aDAI", "waDAI", 18, dai); + ERC4626TestToken waWETH = createERC4626("Wrapped aWETH", "waWETH", 18, weth); // "waUSDC" is deliberately 18 decimals to test one thing at a time. - waUSDC = createERC4626("Wrapped aUSDC", "waUSDC", 18, usdc); + ERC4626TestToken waUSDC = createERC4626("Wrapped aUSDC", "waUSDC", 18, usdc); + + _state.tokensInfo.waDAI = waDAI; + _state.tokensInfo.waWETH = waWETH; + _state.tokensInfo.waUSDC = waUSDC; // Fill the ERC4626 token list. - erc4626Tokens.push(waDAI); - erc4626Tokens.push(waWETH); - erc4626Tokens.push(waUSDC); + _state.tokensInfo.erc4626Tokens.push(waDAI); + _state.tokensInfo.erc4626Tokens.push(waWETH); + _state.tokensInfo.erc4626Tokens.push(waUSDC); // Create users for testing. - (admin, adminKey) = createUser("admin"); - (lp, lpKey) = createUser("lp"); - (alice, aliceKey) = createUser("alice"); - (bob, bobKey) = createUser("bob"); - (hacker, hackerKey) = createUser("hacker"); + (address admin, uint256 adminKey) = createUser("admin"); + (address lp, uint256 lpKey) = createUser("lp"); + (address alice, uint256 aliceKey) = createUser("alice"); + (address bob, uint256 bobKey) = createUser("bob"); + (address hacker, uint256 hackerKey) = createUser("hacker"); address brokeNonPay; + uint256 brokeUserKey; (brokeNonPay, brokeUserKey) = makeAddrAndKey("broke"); - broke = payable(brokeNonPay); - vm.label(broke, "broke"); + vm.label(brokeNonPay, "broke"); + + _state.accounts.admin = admin; + _state.accounts.adminKey = adminKey; + _state.accounts.lp = lp; + _state.accounts.lpKey = lpKey; + _state.accounts.alice = alice; + _state.accounts.aliceKey = aliceKey; + _state.accounts.bob = bob; + _state.accounts.bobKey = bobKey; + _state.accounts.hacker = hacker; + _state.accounts.hackerKey = hackerKey; + _state.accounts.broke = payable(brokeNonPay); + _state.accounts.brokeUserKey = brokeUserKey; + + _state.accounts.users.push(admin); + _state.accounts.userKeys.push(adminKey); + _state.accounts.users.push(lp); + _state.accounts.userKeys.push(lpKey); + _state.accounts.users.push(alice); + _state.accounts.userKeys.push(aliceKey); + _state.accounts.users.push(bob); + _state.accounts.userKeys.push(bobKey); + _state.accounts.users.push(hacker); + _state.accounts.userKeys.push(hackerKey); + _state.accounts.users.push(payable(brokeNonPay)); + _state.accounts.userKeys.push(brokeUserKey); // Must mock rates after giving wrapped tokens to users, but before creating pools and initializing buffers. mockERC4626TokenRates(); - // Fill the users list - users.push(admin); - userKeys.push(adminKey); - users.push(lp); - userKeys.push(lpKey); - users.push(alice); - userKeys.push(aliceKey); - users.push(bob); - userKeys.push(bobKey); - users.push(broke); - userKeys.push(brokeUserKey); + _initialized = true; + } + + function isBaseTestInitialized() internal view returns (bool) { + return _initialized; + } + + function getBaseTestState() internal view returns (BaseTestState memory) { + return _state; } + function getTokens() internal view returns (TokensInfo memory) { + return _state.tokensInfo; + } + + function getAccounts() internal view returns (Accounts memory) { + return _state.accounts; + } + + // -------------------- Helpers -------------------- + /** * @notice Manipulate rates of ERC4626 tokens. * @dev It's important to not have a 1:1 rate when testing ERC4626 tokens, so we can differentiate between * wrapped and underlying amounts. For certain tests, we may need to override these rates for simplicity. */ function mockERC4626TokenRates() internal virtual { - waDAI.inflateUnderlyingOrWrapped(0, 6 * defaultBalance); - waUSDC.inflateUnderlyingOrWrapped(23 * defaultBalance, 0); + _state.tokensInfo.waDAI.inflateUnderlyingOrWrapped(0, 6 * _defaultBalance); + _state.tokensInfo.waUSDC.inflateUnderlyingOrWrapped(23 * _defaultBalance, 0); } function getSortedIndexes( @@ -186,29 +249,35 @@ abstract contract BaseTest is Test, GasSnapshot { /// @dev Generates a user, labels its address, and funds it with test assets. function createUser(string memory name) internal returns (address payable, uint256) { + return createUser(name, _defaultBalance); + } + + /// @dev Generates a user, labels its address, and funds it with test assets. + function createUser(string memory name, uint256 balance) internal returns (address payable, uint256) { (address user, uint256 key) = makeAddrAndKey(name); vm.label(user, name); - vm.deal(payable(user), defaultBalance); + vm.deal(payable(user), balance); - for (uint256 i = 0; i < tokens.length; ++i) { - deal(address(tokens[i]), user, defaultBalance); + for (uint256 i = 0; i < _state.tokensInfo.tokens.length; ++i) { + deal(address(_state.tokensInfotokens[i]), user, balance); } + ERC4626TestToken[] memory erc4626Tokens = _state.tokensInfo.erc4626Tokens; for (uint256 i = 0; i < erc4626Tokens.length; ++i) { // Give underlying tokens to the user, for depositing in the wrapped token. - if (erc4626Tokens[i].asset() == address(weth)) { - vm.deal(user, user.balance + defaultBalance); + if (erc4626Tokens[i].asset() == address(_state.tokensInfo.weth)) { + vm.deal(user, user.balance + balance); vm.prank(user); - weth.deposit{ value: defaultBalance }(); + _state.tokensInfo.weth.deposit{ value: balance }(); } else { - ERC20TestToken(erc4626Tokens[i].asset()).mint(user, defaultBalance); + ERC20TestToken(erc4626Tokens[i].asset()).mint(user, balance); } // Deposit underlying to mint wrapped tokens to the user. vm.startPrank(user); - IERC20(erc4626Tokens[i].asset()).approve(address(erc4626Tokens[i]), defaultBalance); - erc4626Tokens[i].deposit(defaultBalance, user); + IERC20(erc4626Tokens[i].asset()).approve(address(erc4626Tokens[i]), balance); + erc4626Tokens[i].deposit(balance, user); vm.stopPrank(); } diff --git a/pkg/vault/test/foundry/AuxiliaryEvent.t.sol b/pkg/vault/test/foundry/AuxiliaryEvent.t.sol index 920af11fa..4ea96db6c 100644 --- a/pkg/vault/test/foundry/AuxiliaryEvent.t.sol +++ b/pkg/vault/test/foundry/AuxiliaryEvent.t.sol @@ -9,7 +9,7 @@ import { IVaultErrors } from "@balancer-labs/v3-interfaces/contracts/vault/IVaul import { PoolMock } from "../../contracts/test/PoolMock.sol"; -import { BaseVaultTest } from "./utils/BaseVaultTest.sol"; +import { BaseTestState, BaseVaultTest } from "./utils/BaseVaultTest.sol"; contract AuxiliaryEventTest is BaseVaultTest { function setUp() public virtual override { @@ -17,10 +17,12 @@ contract AuxiliaryEventTest is BaseVaultTest { } function testWithNonPoolCall() public { + BaseTestState bState = getBaseTestState(); + // Only registered pools can emit aux event - vm.expectRevert(abi.encodeWithSelector(IVaultErrors.PoolNotRegistered.selector, admin)); + vm.expectRevert(abi.encodeWithSelector(IVaultErrors.PoolNotRegistered.selector, bState.accounts.admin)); - vm.prank(admin); + vm.prank(bState.accounts.admin); vault.emitAuxiliaryEvent("TestEvent", abi.encode(777)); } diff --git a/pkg/vault/test/foundry/BalancerPoolTokenTest.t.sol b/pkg/vault/test/foundry/BalancerPoolTokenTest.t.sol index ce917fe83..8b920c539 100644 --- a/pkg/vault/test/foundry/BalancerPoolTokenTest.t.sol +++ b/pkg/vault/test/foundry/BalancerPoolTokenTest.t.sol @@ -19,7 +19,7 @@ import { FixedPoint } from "@balancer-labs/v3-solidity-utils/contracts/math/Fixe import { BalancerPoolToken } from "../../contracts/BalancerPoolToken.sol"; import { PoolMock } from "../../contracts/test/PoolMock.sol"; -import { BaseVaultTest } from "./utils/BaseVaultTest.sol"; +import { BaseTestState, BaseVaultTest } from "./utils/BaseVaultTest.sol"; contract BalancerPoolTokenTest is BaseVaultTest { using ArrayHelpers for *; @@ -481,8 +481,10 @@ contract BalancerPoolTokenTest is BaseVaultTest { } function testGetRate() public { + BaseTestState bState = getBaseTestState(); + // Init pool, so it has a BPT supply and rate can be calculated. - vm.startPrank(lp); + vm.startPrank(bState.accounts.lp); IERC20[] memory tokens = vault.getPoolTokens(address(poolToken)); router.initialize( address(poolToken), diff --git a/pkg/vault/test/foundry/BatchRouter.t.sol b/pkg/vault/test/foundry/BatchRouter.t.sol index 5bbad22f7..4a19d40db 100644 --- a/pkg/vault/test/foundry/BatchRouter.t.sol +++ b/pkg/vault/test/foundry/BatchRouter.t.sol @@ -10,7 +10,7 @@ import { IBatchRouter } from "@balancer-labs/v3-interfaces/contracts/vault/IBatc import { MOCK_BATCH_ROUTER_VERSION } from "../../contracts/test/BatchRouterMock.sol"; import { RouterCommon } from "../../contracts/RouterCommon.sol"; -import { BaseVaultTest } from "./utils/BaseVaultTest.sol"; +import { BaseTestState, BaseVaultTest } from "./utils/BaseVaultTest.sol"; contract BatchRouterTest is BaseVaultTest { function setUp() public virtual override { @@ -36,9 +36,11 @@ contract BatchRouterTest is BaseVaultTest { } function testQuerySingleStepRemove() public { + BaseTestState memory state = getBaseTestState(); + // create a swap step and query the batch router, where the first token is the bpt. IBatchRouter.SwapPathStep[] memory step = new IBatchRouter.SwapPathStep[](1); - step[0] = IBatchRouter.SwapPathStep(address(pool), IERC20(address(dai)), false); + step[0] = IBatchRouter.SwapPathStep(address(pool), IERC20(address(state.tokensInfo.dai)), false); uint256 totalSupply = IERC20(pool).totalSupply(); uint256 bptAmountIn = 1e18; @@ -55,7 +57,7 @@ contract BatchRouterTest is BaseVaultTest { IBatchRouter.SwapPathExactAmountIn[] memory paths = new IBatchRouter.SwapPathExactAmountIn[](1); paths[0] = path; - vm.prank(alice, address(0)); + vm.prank(state.accounts.alice, address(0)); batchRouter.querySwapExactIn(paths, address(0), bytes("")); } } diff --git a/pkg/vault/test/foundry/utils/BaseVaultTest.sol b/pkg/vault/test/foundry/utils/BaseVaultTest.sol index 2497ac61e..9ec154687 100644 --- a/pkg/vault/test/foundry/utils/BaseVaultTest.sol +++ b/pkg/vault/test/foundry/utils/BaseVaultTest.sol @@ -17,7 +17,7 @@ import { IVault } from "@balancer-labs/v3-interfaces/contracts/vault/IVault.sol" import { CastingHelpers } from "@balancer-labs/v3-solidity-utils/contracts/helpers/CastingHelpers.sol"; import { ArrayHelpers } from "@balancer-labs/v3-solidity-utils/contracts/test/ArrayHelpers.sol"; -import { BaseTest } from "@balancer-labs/v3-solidity-utils/test/foundry/utils/BaseTest.sol"; +import { BaseTest, BaseTestState } from "@balancer-labs/v3-solidity-utils/test/foundry/utils/BaseTest.sol"; import { FixedPoint } from "@balancer-labs/v3-solidity-utils/contracts/math/FixedPoint.sol"; import { BasicAuthorizerMock } from "../../../contracts/test/BasicAuthorizerMock.sol"; @@ -143,6 +143,8 @@ abstract contract BaseVaultTest is VaultContractsDeployer, VaultStorage, BaseTes function _setUpBaseVaultTest() internal { vault = deployVaultMock(vaultMockMinTradeAmount, vaultMockMinWrapAmount); + BaseTestState memory bState = getBaseTestState(); + vm.label(address(vault), "vault"); vaultExtension = IVaultExtension(vault.getVaultExtension()); vm.label(address(vaultExtension), "vaultExtension"); @@ -152,13 +154,17 @@ abstract contract BaseVaultTest is VaultContractsDeployer, VaultStorage, BaseTes vm.label(address(authorizer), "authorizer"); factoryMock = PoolFactoryMock(address(vault.getPoolFactoryMock())); vm.label(address(factoryMock), "factory"); - router = deployRouterMock(IVault(address(vault)), weth, permit2); + router = deployRouterMock(IVault(address(vault)), bState.tokensInfo.weth, permit2); vm.label(address(router), "router"); - batchRouter = deployBatchRouterMock(IVault(address(vault)), weth, permit2); + batchRouter = deployBatchRouterMock(IVault(address(vault)), bState.tokensInfo.weth, permit2); vm.label(address(batchRouter), "batch router"); - compositeLiquidityRouter = new CompositeLiquidityRouterMock(IVault(address(vault)), weth, permit2); + compositeLiquidityRouter = new CompositeLiquidityRouterMock( + IVault(address(vault)), + bState.tokensInfo.weth, + permit2 + ); vm.label(address(compositeLiquidityRouter), "composite liquidity router"); - bufferRouter = deployBufferRouterMock(IVault(address(vault)), weth, permit2); + bufferRouter = deployBufferRouterMock(IVault(address(vault)), bState.tokensInfo.weth, permit2); vm.label(address(bufferRouter), "buffer router"); feeController = vault.getProtocolFeeController(); vm.label(address(feeController), "fee controller"); @@ -166,6 +172,7 @@ abstract contract BaseVaultTest is VaultContractsDeployer, VaultStorage, BaseTes poolHooksContract = createHook(); (pool, poolArguments) = createPool(); + address[] memory users = bState.accounts.users; // Approve vault allowances. for (uint256 i = 0; i < users.length; ++i) { address user = users[i]; @@ -179,6 +186,9 @@ abstract contract BaseVaultTest is VaultContractsDeployer, VaultStorage, BaseTes } function approveForSender() internal virtual { + BaseTestState memory bState = getBaseTestState(); + + IERC20[] memory tokens = bState.tokens; for (uint256 i = 0; i < tokens.length; ++i) { tokens[i].approve(address(permit2), type(uint256).max); permit2.approve(address(tokens[i]), address(router), type(uint160).max, type(uint48).max); @@ -187,6 +197,7 @@ abstract contract BaseVaultTest is VaultContractsDeployer, VaultStorage, BaseTes permit2.approve(address(tokens[i]), address(compositeLiquidityRouter), type(uint160).max, type(uint48).max); } + IERC4626[] memory erc4626Tokens = bState.tokensInfo.erc4626Tokens; for (uint256 i = 0; i < erc4626Tokens.length; ++i) { erc4626Tokens[i].approve(address(permit2), type(uint256).max); permit2.approve(address(erc4626Tokens[i]), address(router), type(uint160).max, type(uint48).max); @@ -206,6 +217,7 @@ abstract contract BaseVaultTest is VaultContractsDeployer, VaultStorage, BaseTes } function approveForPool(IERC20 bpt) internal virtual { + address[] memory users = getBaseTestState().accounts.users; for (uint256 i = 0; i < users.length; ++i) { vm.startPrank(users[i]); @@ -225,7 +237,7 @@ abstract contract BaseVaultTest is VaultContractsDeployer, VaultStorage, BaseTes } function initPool() internal virtual { - vm.startPrank(lp); + vm.startPrank(getBaseTestState().accounts.lp); _initPool(pool, [poolInitAmount, poolInitAmount].toMemoryArray(), 0); vm.stopPrank(); } @@ -241,7 +253,8 @@ abstract contract BaseVaultTest is VaultContractsDeployer, VaultStorage, BaseTes } function createPool() internal virtual returns (address, bytes memory) { - return _createPool([address(dai), address(usdc)].toMemoryArray(), "pool"); + BaseTestState memory bState = getBaseTestState(); + return _createPool([address(bState.tokensInfo.dai), address(bState.tokensInfo.usdc)].toMemoryArray(), "pool"); } function _createPool( @@ -254,7 +267,12 @@ abstract contract BaseVaultTest is VaultContractsDeployer, VaultStorage, BaseTes newPool = factoryMock.createPool(name, symbol); vm.label(newPool, label); - factoryMock.registerTestPool(newPool, vault.buildTokenConfig(tokens.asIERC20()), poolHooksContract, lp); + factoryMock.registerTestPool( + newPool, + vault.buildTokenConfig(tokens.asIERC20()), + poolHooksContract, + getBaseTestState().accounts.lp + ); poolArgs = abi.encode(vault, name, symbol); } @@ -288,11 +306,13 @@ abstract contract BaseVaultTest is VaultContractsDeployer, VaultStorage, BaseTes } function getBalances(address user, Rounding invariantRounding) internal view returns (Balances memory balances) { + BaseTestState memory bState = getBaseTestState(); + balances.userBpt = IERC20(pool).balanceOf(user); - balances.aliceBpt = IERC20(pool).balanceOf(alice); - balances.bobBpt = IERC20(pool).balanceOf(bob); + balances.aliceBpt = IERC20(pool).balanceOf(bState.accounts.alice); + balances.bobBpt = IERC20(pool).balanceOf(bState.accounts.bob); balances.hookBpt = IERC20(pool).balanceOf(poolHooksContract); - balances.lpBpt = IERC20(pool).balanceOf(lp); + balances.lpBpt = IERC20(pool).balanceOf(bState.accounts.lp); balances.poolSupply = IERC20(pool).totalSupply(); @@ -316,28 +336,31 @@ abstract contract BaseVaultTest is VaultContractsDeployer, VaultStorage, BaseTes /// @dev A different function is needed to measure token balances when tracking tokens across multiple pools. function getBalances(address user, IERC20[] memory tokensToTrack) internal view returns (Balances memory balances) { + BaseTestState memory bState = getBaseTestState(); balances.userBpt = IERC20(pool).balanceOf(user); - balances.aliceBpt = IERC20(pool).balanceOf(alice); - balances.bobBpt = IERC20(pool).balanceOf(bob); + balances.aliceBpt = IERC20(pool).balanceOf(bState.accounts.alice); + balances.bobBpt = IERC20(pool).balanceOf(bState.accounts.bob); balances.hookBpt = IERC20(pool).balanceOf(poolHooksContract); - balances.lpBpt = IERC20(pool).balanceOf(lp); + balances.lpBpt = IERC20(pool).balanceOf(bState.accounts.lp); _fillBalances(balances, user, tokensToTrack); } function _fillBalances(Balances memory balances, address user, IERC20[] memory tokens) private view { + BaseTestState memory bState = getBaseTestState(); + uint256 numTokens = tokens.length; balances.userTokens = new uint256[](numTokens); balances.userEth = user.balance; balances.aliceTokens = new uint256[](numTokens); - balances.aliceEth = alice.balance; + balances.aliceEth = bState.accounts.alice.balance; balances.bobTokens = new uint256[](numTokens); - balances.bobEth = bob.balance; + balances.bobEth = bState.accounts.bob.balance; balances.hookTokens = new uint256[](numTokens); balances.hookEth = poolHooksContract.balance; balances.lpTokens = new uint256[](numTokens); - balances.lpEth = lp.balance; + balances.lpEth = bState.accounts.lp.balance; balances.vaultTokens = new uint256[](numTokens); balances.vaultEth = address(vault).balance; balances.vaultReserves = new uint256[](numTokens); @@ -345,10 +368,10 @@ abstract contract BaseVaultTest is VaultContractsDeployer, VaultStorage, BaseTes for (uint256 i = 0; i < numTokens; ++i) { // Don't assume token ordering. balances.userTokens[i] = tokens[i].balanceOf(user); - balances.aliceTokens[i] = tokens[i].balanceOf(alice); - balances.bobTokens[i] = tokens[i].balanceOf(bob); + balances.aliceTokens[i] = tokens[i].balanceOf(bState.accounts.alice); + balances.bobTokens[i] = tokens[i].balanceOf(bState.accounts.bob); balances.hookTokens[i] = tokens[i].balanceOf(poolHooksContract); - balances.lpTokens[i] = tokens[i].balanceOf(lp); + balances.lpTokens[i] = tokens[i].balanceOf(bState.accounts.lp); balances.vaultTokens[i] = tokens[i].balanceOf(address(vault)); balances.vaultReserves[i] = vault.getReservesOf(tokens[i]); }