Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: separate integration tests from unit tests #11

Merged
merged 1 commit into from
Jan 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ Logic:

Tests:

- [ ] Separate integration tests from unit tests (separate PR)
- [x] Separate integration tests from unit tests (separate PR)
- [x] Move all utils to test/common/

Considerations:

Expand Down
188 changes: 1 addition & 187 deletions test/FeeCollector.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,8 @@ import { Test } from "forge-std/Test.sol";
// Local Imports
import { PositionFactory } from "src/PositionFactory.sol";
import { FeeCollector } from "src/FeeCollector.sol";
import {
Assets,
AAVE_ORACLE,
CONTRACT_DEPLOYER,
FEE_COLLECTOR,
TEST_CLIENT,
PROTOCOL_FEE,
CLIENT_RATE,
USDC,
WETH,
WBTC
} from "test/common/Constants.t.sol";
import { Assets, CONTRACT_DEPLOYER, TEST_CLIENT, CLIENT_RATE, USDC, WETH, WBTC } from "test/common/Constants.t.sol";
import { TokenUtils } from "test/common/utils/TokenUtils.t.sol";
import { IFeeCollector } from "src/interfaces/IFeeCollector.sol";
import { IAaveOracle } from "src/interfaces/aave/IAaveOracle.sol";
import { IPosition } from "src/interfaces/IPosition.sol";
import { IERC20 } from "src/interfaces/token/IERC20.sol";

contract FeeCollectorTest is Test, TokenUtils {
Expand All @@ -49,9 +35,6 @@ contract FeeCollectorTest is Test, TokenUtils {
address public positionOwner = address(this);
address public feeCollectorAddr;

// Events
event Short(uint256 cAmt, uint256 dAmt, uint256 bAmt);

function setUp() public {
// Setup: use mainnet fork
mainnetFork = vm.createFork(vm.envString("RPC_URL"));
Expand Down Expand Up @@ -88,15 +71,6 @@ contract FeeCollectorTest is Test, TokenUtils {
positionAddr = positionFactory.createPosition(WETH, USDC, WETH);
newPosition = TestPosition({ addr: positionAddr, cToken: WETH, dToken: USDC, bToken: WETH });
positions.push(newPosition);

// Mock AaveOracle
for (uint256 i; i < supportedAssets.length; i++) {
vm.mockCall(
AAVE_ORACLE,
abi.encodeWithSelector(IAaveOracle(AAVE_ORACLE).getAssetPrice.selector, supportedAssets[i]),
abi.encode(assets.prices(supportedAssets[i]))
);
}
}

/// @dev
Expand Down Expand Up @@ -434,163 +408,3 @@ contract FeeCollectorTest is Test, TokenUtils {
assertEq(postContractBalance, preContractBalance + _amount);
}
}

contract FeeCollectorIntegrationTest is Test, TokenUtils {
/* solhint-disable func-name-mixedcase */

struct TestPosition {
address addr;
address cToken;
address dToken;
address bToken;
}

// Errors
error OwnableUnauthorizedAccount(address account);

// Test contracts
PositionFactory public positionFactory;
Assets public assets;
TestPosition[] public positions;

// Test Storage
uint256 public mainnetFork;
address public positionOwner = address(this);

// Events
event Short(uint256 cAmt, uint256 dAmt, uint256 bAmt);

function setUp() public {
// Setup: use mainnet fork
mainnetFork = vm.createFork(vm.envString("RPC_URL"));
vm.selectFork(mainnetFork);

// Deploy assets
assets = new Assets();
address[4] memory supportedAssets = assets.getSupported();

// Deploy FeeCollector
vm.prank(CONTRACT_DEPLOYER);
deployCodeTo("FeeCollector.sol", abi.encode(CONTRACT_DEPLOYER), FEE_COLLECTOR);

// Deploy PositionFactory
vm.prank(CONTRACT_DEPLOYER);
positionFactory = new PositionFactory(CONTRACT_DEPLOYER);

// Set client rate
vm.prank(CONTRACT_DEPLOYER);
IFeeCollector(FEE_COLLECTOR).setClientRate(CLIENT_RATE);

// Deploy and store four position contracts - one for each supported asset as collateral
address positionAddr;
TestPosition memory newPosition;
for (uint256 i; i < supportedAssets.length; i++) {
if (supportedAssets[i] != WETH) {
positionAddr = positionFactory.createPosition(supportedAssets[i], WETH, WBTC);
newPosition =
TestPosition({ addr: positionAddr, cToken: supportedAssets[i], dToken: WETH, bToken: WBTC });
positions.push(newPosition);
}
}
positionAddr = positionFactory.createPosition(WETH, USDC, WETH);
newPosition = TestPosition({ addr: positionAddr, cToken: WETH, dToken: USDC, bToken: WETH });
positions.push(newPosition);

// Mock AaveOracle
for (uint256 i; i < supportedAssets.length; i++) {
vm.mockCall(
AAVE_ORACLE,
abi.encodeWithSelector(IAaveOracle(AAVE_ORACLE).getAssetPrice.selector, supportedAssets[i]),
abi.encode(assets.prices(supportedAssets[i]))
);
}
}

/// @dev
// - The active fork should be the forked network created in the setup
function test_ActiveFork() public {
assertEq(vm.activeFork(), mainnetFork, "vm.activeFork() != mainnetFork");
}

/// @dev
// - The FeeCollector's cToken balance should increase by protocolFee
// - The cToken totalClientBalances should increase by clientFee
// - The client's cToken balance on the FeeCollector contract should increase by clientFee
function testFuzz_CollectFeesWithClientIntegrated(uint256 _cAmt) external payable {
for (uint256 i; i < positions.length; i++) {
// Test Variables
address positionAddr = positions[i].addr;
address cToken = positions[i].cToken;

// Bound fuzzed variables
_cAmt = bound(_cAmt, assets.minCAmts(cToken), assets.maxCAmts(cToken));

// Expectations
uint256 protocolFee = (_cAmt * PROTOCOL_FEE) / 1000;
uint256 clientFee = (protocolFee * CLIENT_RATE) / 100;

// Fund positionOwner with _cAmt of cToken
_fund(positionOwner, cToken, _cAmt);

// Approve Position contract to spend collateral
IERC20(cToken).approve(positionAddr, _cAmt);

// Pre-act balances
uint256 preContractBalance = IERC20(cToken).balanceOf(FEE_COLLECTOR);
uint256 preTotalClientBalances = IFeeCollector(FEE_COLLECTOR).totalClientBalances(cToken);
uint256 preClientFeeBalance = IFeeCollector(FEE_COLLECTOR).balances(TEST_CLIENT, cToken);

// Act: increase short position
IPosition(positionAddr).short(_cAmt, 50, 0, 3000, TEST_CLIENT);

// Post-act balances
uint256 postContractBalance = IERC20(cToken).balanceOf(FEE_COLLECTOR);
uint256 postTotalClientBalances = IFeeCollector(FEE_COLLECTOR).totalClientBalances(cToken);
uint256 postClientFeeBalance = IFeeCollector(FEE_COLLECTOR).balances(TEST_CLIENT, cToken);

// Assertions
assertEq(postContractBalance, preContractBalance + protocolFee);
assertEq(postTotalClientBalances, preTotalClientBalances + clientFee);
assertEq(postClientFeeBalance, preClientFeeBalance + clientFee);
}
}

/// @dev
// - The FeeCollector's cToken balance should increase by protocolFee
// - The cToken totalClientBalances should not change
// - The above should be true when _client is sent as address(0)
function testFuzz_CollectFeesNoClientIntegrated(uint256 _cAmt) external payable {
for (uint256 i; i < positions.length; i++) {
// Test Variables
address positionAddr = positions[i].addr;
address cToken = positions[i].cToken;

// Bound fuzzed variables
_cAmt = bound(_cAmt, assets.minCAmts(cToken), assets.maxCAmts(cToken));

// Expectations
uint256 protocolFee = (_cAmt * PROTOCOL_FEE) / 1000;

// Fund positionOwner with _cAmt of cToken
_fund(positionOwner, cToken, _cAmt);

// Approve Position contract to spend collateral
IERC20(cToken).approve(positionAddr, _cAmt);

// Pre-act balances
uint256 preContractBalance = IERC20(cToken).balanceOf(FEE_COLLECTOR);
uint256 preTotalClientBalances = IFeeCollector(FEE_COLLECTOR).totalClientBalances(cToken);

// Act: increase short position
IPosition(positionAddr).short(_cAmt, 50, 0, 3000, address(0));

// Post-act balances
uint256 postContractBalance = IERC20(cToken).balanceOf(FEE_COLLECTOR);
uint256 postTotalClientBalances = IFeeCollector(FEE_COLLECTOR).totalClientBalances(cToken);

// Assertions
assertEq(postContractBalance, preContractBalance + protocolFee);
assertEq(postTotalClientBalances, preTotalClientBalances);
}
}
}
Loading
Loading