Skip to content

Commit

Permalink
test: adapters unit tests (#70)
Browse files Browse the repository at this point in the history
  • Loading branch information
lekhovitsky authored Oct 26, 2023
1 parent a12321d commit 729ba71
Show file tree
Hide file tree
Showing 99 changed files with 4,876 additions and 11,416 deletions.
7 changes: 5 additions & 2 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,14 @@ jobs:
with:
version: nightly

- name: Run forge install
run: forge install

- name: Run forge unit tests
run: forge test --no-match-test _live_
run: forge test --match-test test_U

- name: Run forge integration tests
run: forge test --match-test _live_ --fork-url ${{ secrets.LIVE_TESTS_FORK }} --chain-id 1337
run: forge test --match-test _live_ --fork-url ${{ secrets.MAINNET_TESTS_FORK }} --chain-id 1337

- name: Perform checks
run: |
Expand Down
36 changes: 18 additions & 18 deletions contracts/adapters/AbstractAdapter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ abstract contract AbstractAdapter is IAdapter, ACLTrait {
/// @param _creditManager Credit manager to connect the adapter to
/// @param _targetContract Address of the adapted contract
constructor(address _creditManager, address _targetContract)
ACLTrait(ICreditManagerV3(_creditManager).addressProvider()) // U:[AA-1A]
nonZeroAddress(_targetContract) // U:[AA-1A]
ACLTrait(ICreditManagerV3(_creditManager).addressProvider())
nonZeroAddress(_targetContract)
{
creditManager = _creditManager; // U:[AA-1B]
addressProvider = ICreditManagerV3(_creditManager).addressProvider(); // U:[AA-1B]
targetContract = _targetContract; // U:[AA-1B]
creditManager = _creditManager;
addressProvider = ICreditManagerV3(_creditManager).addressProvider();
targetContract = _targetContract;
}

/// @dev Ensures that caller of the function is credit facade connected to the credit manager
Expand All @@ -42,34 +42,34 @@ abstract contract AbstractAdapter is IAdapter, ACLTrait {
/// @dev Ensures that caller is credit facade connected to the credit manager
function _revertIfCallerNotCreditFacade() internal view {
if (msg.sender != ICreditManagerV3(creditManager).creditFacade()) {
revert CallerNotCreditFacadeException(); // U:[AA-2]
revert CallerNotCreditFacadeException();
}
}

/// @dev Ensures that active credit account is set and returns its address
function _creditAccount() internal view returns (address) {
return ICreditManagerV3(creditManager).getActiveCreditAccountOrRevert(); // U:[AA-3]
return ICreditManagerV3(creditManager).getActiveCreditAccountOrRevert();
}

/// @dev Ensures that token is registered as collateral in the credit manager and returns its mask
function _getMaskOrRevert(address token) internal view returns (uint256 tokenMask) {
tokenMask = ICreditManagerV3(creditManager).getTokenMaskOrRevert(token); // U:[AA-4]
tokenMask = ICreditManagerV3(creditManager).getTokenMaskOrRevert(token);
}

/// @dev Approves target contract to spend given token from the active credit account
/// Reverts if active credit account is not set or token is not registered as collateral
/// @param token Token to approve
/// @param amount Amount to approve
function _approveToken(address token, uint256 amount) internal {
ICreditManagerV3(creditManager).approveCreditAccount(token, amount); // U:[AA-5]
ICreditManagerV3(creditManager).approveCreditAccount(token, amount);
}

/// @dev Executes an external call from the active credit account to the target contract
/// Reverts if active credit account is not set
/// @param callData Data to call the target contract with
/// @return result Call result
function _execute(bytes memory callData) internal returns (bytes memory result) {
return ICreditManagerV3(creditManager).execute(callData); // U:[AA-6]
return ICreditManagerV3(creditManager).execute(callData);
}

/// @dev Executes a swap operation without input token approval
Expand All @@ -86,10 +86,10 @@ abstract contract AbstractAdapter is IAdapter, ACLTrait {
internal
returns (uint256 tokensToEnable, uint256 tokensToDisable, bytes memory result)
{
tokensToEnable = _getMaskOrRevert(tokenOut); // U:[AA-7]
tokensToEnable = _getMaskOrRevert(tokenOut);
uint256 tokenInMask = _getMaskOrRevert(tokenIn);
if (disableTokenIn) tokensToDisable = tokenInMask; // U:[AA-7]
result = _execute(callData); // U:[AA-7]
if (disableTokenIn) tokensToDisable = tokenInMask;
result = _execute(callData);
}

/// @dev Executes a swap operation with maximum input token approval, and revokes approval after the call
Expand All @@ -107,10 +107,10 @@ abstract contract AbstractAdapter is IAdapter, ACLTrait {
internal
returns (uint256 tokensToEnable, uint256 tokensToDisable, bytes memory result)
{
tokensToEnable = _getMaskOrRevert(tokenOut); // U:[AA-8]
if (disableTokenIn) tokensToDisable = _getMaskOrRevert(tokenIn); // U:[AA-8]
_approveToken(tokenIn, type(uint256).max); // U:[AA-8]
result = _execute(callData); // U:[AA-8]
_approveToken(tokenIn, 1); // U:[AA-8]
tokensToEnable = _getMaskOrRevert(tokenOut);
if (disableTokenIn) tokensToDisable = _getMaskOrRevert(tokenIn);
_approveToken(tokenIn, type(uint256).max);
result = _execute(callData);
_approveToken(tokenIn, 1);
}
}
44 changes: 23 additions & 21 deletions contracts/adapters/aave/AaveV2_LendingPoolAdapter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ contract AaveV2_LendingPoolAdapter is AbstractAdapter, IAaveV2_LendingPoolAdapte
/// @notice Constructor
/// @param _creditManager Credit manager address
/// @param _lendingPool Lending pool address
constructor(address _creditManager, address _lendingPool) AbstractAdapter(_creditManager, _lendingPool) {}
constructor(address _creditManager, address _lendingPool)
AbstractAdapter(_creditManager, _lendingPool) // U:[AAVE2-1]
{}

/// @dev Returns aToken address for given underlying token
function _aToken(address underlying) internal view returns (address) {
Expand All @@ -39,30 +41,30 @@ contract AaveV2_LendingPoolAdapter is AbstractAdapter, IAaveV2_LendingPoolAdapte
function deposit(address asset, uint256 amount, address, uint16)
external
override
creditFacadeOnly // F: [AAV2LP-1]
creditFacadeOnly // U:[AAVE2-2]
returns (uint256 tokensToEnable, uint256 tokensToDisable)
{
address creditAccount = _creditAccount();
(tokensToEnable, tokensToDisable) = _deposit(creditAccount, asset, amount, false); // F: [AAV2LP-3]
address creditAccount = _creditAccount(); // U:[AAVE2-3]
(tokensToEnable, tokensToDisable) = _deposit(creditAccount, asset, amount, false); // U:[AAVE2-3]
}

/// @notice Deposit all underlying tokens into Aave in exchange for aTokens, disables underlying
/// @param asset Address of underlying token to deposit
function depositAll(address asset)
external
override
creditFacadeOnly // F: [AAV2LP-1]
creditFacadeOnly // U:[AAVE2-2]
returns (uint256 tokensToEnable, uint256 tokensToDisable)
{
address creditAccount = _creditAccount();
address creditAccount = _creditAccount(); // U:[AAVE2-4]

uint256 amount = IERC20(asset).balanceOf(creditAccount);
uint256 amount = IERC20(asset).balanceOf(creditAccount); // U:[AAVE2-4]
if (amount <= 1) return (0, 0);
unchecked {
--amount;
--amount; // U:[AAVE2-4]
}

(tokensToEnable, tokensToDisable) = _deposit(creditAccount, asset, amount, true); // F: [AAV2LP-4]
(tokensToEnable, tokensToDisable) = _deposit(creditAccount, asset, amount, true); // U:[AAVE2-4]
}

/// @dev Internal implementation of `deposit` and `depositAll` functions
Expand All @@ -79,7 +81,7 @@ contract AaveV2_LendingPoolAdapter is AbstractAdapter, IAaveV2_LendingPoolAdapte
_aToken(asset),
abi.encodeCall(ILendingPool.deposit, (asset, amount, creditAccount, 0)),
disableTokenIn
); // F: [AAV2LP-2]
); // U:[AAVE2-3,4]
}

// ----------- //
Expand All @@ -94,14 +96,14 @@ contract AaveV2_LendingPoolAdapter is AbstractAdapter, IAaveV2_LendingPoolAdapte
function withdraw(address asset, uint256 amount, address)
external
override
creditFacadeOnly // F: [AAV2LP-1]
creditFacadeOnly // U:[AAVE2-2]
returns (uint256 tokensToEnable, uint256 tokensToDisable)
{
address creditAccount = _creditAccount();
address creditAccount = _creditAccount(); // U:[AAVE2-5A,5B]
if (amount == type(uint256).max) {
(tokensToEnable, tokensToDisable) = _withdrawAll(creditAccount, asset); // F: [AAV2LP-5B]
(tokensToEnable, tokensToDisable) = _withdrawAll(creditAccount, asset); // U:[AAVE2-5B]
} else {
(tokensToEnable, tokensToDisable) = _withdraw(creditAccount, asset, amount); // F: [AAV2LP-5A]
(tokensToEnable, tokensToDisable) = _withdraw(creditAccount, asset, amount); // U:[AAVE2-5A]
}
}

Expand All @@ -110,11 +112,11 @@ contract AaveV2_LendingPoolAdapter is AbstractAdapter, IAaveV2_LendingPoolAdapte
function withdrawAll(address asset)
external
override
creditFacadeOnly // F: [AAV2LP-1]
creditFacadeOnly // U:[AAVE2-2]
returns (uint256 tokensToEnable, uint256 tokensToDisable)
{
address creditAccount = _creditAccount();
(tokensToEnable, tokensToDisable) = _withdrawAll(creditAccount, asset); // F: [AAV2LP-6]
address creditAccount = _creditAccount(); // U:[AAVE2-6]
(tokensToEnable, tokensToDisable) = _withdrawAll(creditAccount, asset); // U:[AAVE2-6]
}

/// @dev Internal implementation of `withdraw` functionality
Expand All @@ -127,7 +129,7 @@ contract AaveV2_LendingPoolAdapter is AbstractAdapter, IAaveV2_LendingPoolAdapte
returns (uint256 tokensToEnable, uint256 tokensToDisable)
{
(tokensToEnable, tokensToDisable,) =
_executeSwapNoApprove(_aToken(asset), asset, _encodeWithdraw(creditAccount, asset, amount), false); // F: [AAV2LP-2]
_executeSwapNoApprove(_aToken(asset), asset, _encodeWithdraw(creditAccount, asset, amount), false); // U:[AAVE2-5A]
}

/// @dev Internal implementation of `withdrawAll` functionality
Expand All @@ -140,14 +142,14 @@ contract AaveV2_LendingPoolAdapter is AbstractAdapter, IAaveV2_LendingPoolAdapte
returns (uint256 tokensToEnable, uint256 tokensToDisable)
{
address aToken = _aToken(asset);
uint256 amount = IERC20(aToken).balanceOf(creditAccount);
uint256 amount = IERC20(aToken).balanceOf(creditAccount); // U:[AAVE2-5B,6]
if (amount <= 1) return (0, 0);
unchecked {
--amount;
--amount; // U:[AAVE2-5B,6]
}

(tokensToEnable, tokensToDisable,) =
_executeSwapNoApprove(aToken, asset, _encodeWithdraw(creditAccount, asset, amount), true); // F: [AAV2LP-2]
_executeSwapNoApprove(aToken, asset, _encodeWithdraw(creditAccount, asset, amount), true); // U:[AAVE2-5B,6]
}

/// @dev Returns calldata for `ILendingPool.withdraw` call
Expand Down
Loading

0 comments on commit 729ba71

Please sign in to comment.