Skip to content

Commit

Permalink
fix: tests moved to unit folder
Browse files Browse the repository at this point in the history
  • Loading branch information
0xmikko committed Apr 24, 2023
1 parent 038c945 commit 68c5668
Show file tree
Hide file tree
Showing 20 changed files with 234 additions and 201 deletions.
36 changes: 15 additions & 21 deletions contracts/credit/CreditManagerV3.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";

// TRAITS
// LIBS & TRAITS
import {BitMask} from "../libraries/BitMask.sol";
import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import {SanityCheckTrait} from "../traits/SanityCheckTrait.sol";
import {BalanceHelperTrait} from "../traits/BalanceHelperTrait.sol";
Expand Down Expand Up @@ -81,7 +82,8 @@ struct Slot1 {
contract CreditManagerV3 is ICreditManagerV2, SanityCheckTrait, ReentrancyGuard, BalanceHelperTrait {
using SafeERC20 for IERC20;
using Address for address payable;
using SafeCast for uint256;
// using SafeCast for uint256;
using BitMask for uint256;

/// @dev The maximal number of enabled tokens on a single Credit Account
uint8 public override maxAllowedEnabledTokenLength = 12;
Expand Down Expand Up @@ -1112,6 +1114,9 @@ contract CreditManagerV3 is ICreditManagerV2, SanityCheckTrait, ReentrancyGuard,
)
) / PERCENTAGE_FACTOR; // F:[CM-43]

/// Adding fee here
// amountToPool = _amountWithFee(amountToPool);

// If there are any funds left after all respective payments (this
// includes the liquidation premium, since totalFunds is already
// discounted from totalValue), they are recorded to remainingFunds
Expand Down Expand Up @@ -1550,30 +1555,12 @@ contract CreditManagerV3 is ICreditManagerV2, SanityCheckTrait, ReentrancyGuard,
}

function _checkEnabledTokenLength(uint256 enabledTokenMask) internal view {
uint256 totalTokensEnabled = _calcEnabledTokens(enabledTokenMask);
uint256 totalTokensEnabled = enabledTokenMask.calcEnabledTokens();
if (totalTokensEnabled > maxAllowedEnabledTokenLength) {
revert TooManyEnabledTokensException();
}
}

/// @dev Calculates the number of enabled tokens, based on the
/// provided token mask
/// @param enabledTokenMask Bit mask encoding a set of enabled tokens
function _calcEnabledTokens(uint256 enabledTokenMask) internal pure returns (uint256 totalTokensEnabled) {
// Bit mask is a number encoding enabled tokens as 1's;
// Therefore, to count the number of enabled tokens, we simply
// need to keep shifting the mask by one bit and checking if the rightmost bit is 1,
// until the whole mask is 0;
// Since bit shifting is overflow-safe and the loop has at most 256 steps,
// the whole function can be marked as unsafe to optimize gas
unchecked {
while (enabledTokenMask > 0) {
totalTokensEnabled += enabledTokenMask & 1;
enabledTokenMask >>= 1;
}
}
}

function withdraw(address creditAccount, address to, address token, uint256 amount)
external
override
Expand Down Expand Up @@ -1675,4 +1662,11 @@ contract CreditManagerV3 is ICreditManagerV2, SanityCheckTrait, ReentrancyGuard,
{
amountInUSD = _priceOracle.convertToUSD(amountInToken, token);
}

//
// FEE TOKEN SUPPORT

function _amountWithFee(uint256 amount) internal view virtual returns (uint256) {
return amount;
}
}
6 changes: 6 additions & 0 deletions contracts/interfaces/IWithdrawManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ interface IWithdrawManagerEvents {

/// @dev Emitted when a Credit Facade is removed from BlacklistHelper
event CreditFacadeRemoved(address indexed creditFacade);

event ScheduleDelayedWithdrawal(address indexed to, address indexed token, uint256 amount, uint256 availableAt);

event CancelDelayedWithdrawal(address indexed to, address indexed token, uint256 amount);

event PayDelayedWithdrawal(address indexed to, address indexed token, uint256 amount);
}

interface IWithdrawManager is IWithdrawManagerEvents, IVersion {
Expand Down
35 changes: 35 additions & 0 deletions contracts/libraries/BitMask.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// SPDX-License-Identifier: MIT
// Gearbox Protocol. Generalized leverage for DeFi protocols
// (c) Gearbox Holdings, 2022
pragma solidity ^0.8.17;

/// @title Quota Library
library BitMask {
function calcIndex(uint256 mask) internal pure returns (uint8) {
require(mask > 0);
uint16 lb = 0;
uint16 ub = 256;
uint16 mid = 128;

unchecked {
while (1 << mid & mask == 0) {
if (1 << mid > mask) ub = mid;
else lb = mid;
mid = (lb + ub) / 2;
}
}

return uint8(mid);
}

/// @dev Calculates the number of `1` bits
/// @param enabledTokenMask Bit mask to compute how many bits are set
function calcEnabledTokens(uint256 enabledTokenMask) internal pure returns (uint256 totalTokensEnabled) {
unchecked {
while (enabledTokenMask > 0) {
totalTokensEnabled += enabledTokenMask & 1;
enabledTokenMask >>= 1;
}
}
}
}
2 changes: 1 addition & 1 deletion contracts/pool/Pool4626_USDT.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
pragma solidity ^0.8.10;

import {Pool4626} from "./Pool4626.sol";
import {USDT_Transfer} from "../libraries/USDT_Transfer.sol";
import {USDT_Transfer} from "../traits/USDT_Transfer.sol";
import {IPool4626, Pool4626Opts} from "../interfaces/IPool4626.sol";

/// @title Core pool contract compatible with ERC4626
Expand Down
12 changes: 2 additions & 10 deletions contracts/pool/PoolQuotaKeeper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,6 @@ contract PoolQuotaKeeper is IPoolQuotaKeeper, ACLNonReentrantTrait, ContractsReg
/// @dev Mapping from (user, token) to per-account quota parameters
mapping(address => mapping(address => mapping(address => AccountQuota))) internal accountQuotas;

/// @dev Mapping for cached token masks
mapping(address => mapping(address => uint256)) internal tokenMaskCached;

/// @dev Address of the gauge that determines quota rates
address public gauge;

Expand Down Expand Up @@ -199,13 +196,8 @@ contract PoolQuotaKeeper is IPoolQuotaKeeper, ACLNonReentrantTrait, ContractsReg
accountQuota.cumulativeIndexLU = cumulativeIndexNow;
}

function getTokenMask(address creditManager, address token) internal returns (uint256 mask) {
mask = tokenMaskCached[creditManager][token];
if (mask == 0) {
mask = ICreditManagerV2(creditManager).getTokenMaskOrRevert(token);

tokenMaskCached[creditManager][token] = mask;
}
function getTokenMask(address creditManager, address token) internal view returns (uint256 mask) {
mask = ICreditManagerV2(creditManager).getTokenMaskOrRevert(token);
}

/// @dev Updates all accountQuotas to zero when closing a credit account, and computes the final quota interest change
Expand Down
32 changes: 19 additions & 13 deletions contracts/support/WithdrawManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol
import {ICreditManagerV2} from "../interfaces/ICreditManagerV2.sol";

import {IWithdrawManager, CancellationType} from "../interfaces/IWithdrawManager.sol";

// LIBS & TRAITS
import {BitMask} from "../libraries/BitMask.sol";
import {ACLNonReentrantTrait} from "../traits/ACLNonReentrantTrait.sol";

// EXCEPTIONS
Expand All @@ -32,7 +35,7 @@ struct WithdrawPush {
/// while simultaneously allowing them to recover their funds under a different address
contract WithdrawManager is IWithdrawManager, ACLNonReentrantTrait {
using SafeERC20 for IERC20;
/// @dev mapping from address to supported Credit Facade status
using BitMask for uint256;

mapping(address => bool) public isSupportedCreditManager;

Expand Down Expand Up @@ -88,12 +91,12 @@ contract WithdrawManager is IWithdrawManager, ACLNonReentrantTrait {

uint40 availableAt = uint40(block.timestamp) + delay;

uint8 tokenIndex = _calcIndexFromMask(tokenMask);
uint8 tokenIndex = tokenMask.calcIndex();

delayed[msg.sender][creditAccount][slot] =
WithdrawRequest({tokenIndex: tokenIndex, amount: amount, to: to, availableAt: availableAt});

// emit IncreaseClaimableBalance(token, to, amount);
emit ScheduleDelayedWithdrawal(to, token, amount, availableAt);
}

/// @dev Transfer the sender's current claimable balance in token to a specified address
Expand Down Expand Up @@ -137,15 +140,19 @@ contract WithdrawManager is IWithdrawManager, ACLNonReentrantTrait {
return true;
}
if (pushBeforeDeadline || req.availableAt > block.timestamp) {
_executeWithdrawal(creditManager, req, req.to);
address token = _executeWithdrawal(creditManager, req, req.to);
emit PayDelayedWithdrawal(req.to, token, req.amount);
return true;
}

return false;
}

function _executeWithdrawal(address creditManager, WithdrawRequest storage req, address to) internal {
(address token,) = ICreditManagerV2(creditManager).collateralTokensByMask(1 << req.tokenIndex);
function _executeWithdrawal(address creditManager, WithdrawRequest storage req, address to)
internal
returns (address token)
{
(token,) = ICreditManagerV2(creditManager).collateralTokensByMask(1 << req.tokenIndex);
IERC20(token).safeTransfer(to, req.amount);
req.availableAt = 1;
req.amount = 1;
Expand All @@ -156,10 +163,10 @@ contract WithdrawManager is IWithdrawManager, ACLNonReentrantTrait {
returns (uint256 tokensToEnable)
{
if (req.availableAt > 1) {
_executeWithdrawal(creditManager, req, creditAccount);
address token = _executeWithdrawal(creditManager, req, creditAccount);
tokensToEnable = 1 << req.tokenIndex;
emit CancelDelayedWithdrawal(req.to, token, req.amount);
}
// EVENT HERE
}

function cancelWithdrawals(address creditAccount, CancellationType ctype)
Expand All @@ -177,12 +184,11 @@ contract WithdrawManager is IWithdrawManager, ACLNonReentrantTrait {
}
}

function pushAndClaim(address[] calldata tokens, WithdrawPush[] calldata pushes, address to) external {}

function _calcIndexFromMask(uint256 tokenMask) internal pure returns (uint8 index) {
function pushAndClaim(WithdrawPush[] calldata pushes) external {
uint256 len = pushes.length;
unchecked {
while (tokenMask < (1 << index)) {
++index;
for (uint256 i; i < len; ++i) {
_push(pushes[i].creditManager, pushes[i].creditAccount, false, true);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,34 @@ pragma solidity ^0.8.17;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

import {AccountFactory} from "@gearbox-protocol/core-v2/contracts/core/AccountFactory.sol";
import {CreditFacadeV3} from "../../credit/CreditFacadeV3.sol";
import {CreditFacadeV3} from "../../../credit/CreditFacadeV3.sol";

import {IAddressProvider} from "@gearbox-protocol/core-v2/contracts/interfaces/IAddressProvider.sol";
import {ICreditAccount} from "@gearbox-protocol/core-v2/contracts/interfaces/ICreditAccount.sol";
import {ICreditFacade, MultiCall} from "@gearbox-protocol/core-v2/contracts/interfaces/ICreditFacade.sol";
import {ICreditManagerV2, ICreditManagerV2Events} from "../../interfaces/ICreditManagerV2.sol";
import {ICreditFacadeEvents} from "../../interfaces/ICreditFacade.sol";
import {IPool4626} from "../../interfaces/IPool4626.sol";
import {ICreditManagerV2, ICreditManagerV2Events} from "../../../interfaces/ICreditManagerV2.sol";
import {ICreditFacadeEvents} from "../../../interfaces/ICreditFacade.sol";
import {IPool4626} from "../../../interfaces/IPool4626.sol";

import "../lib/constants.sol";
import {BalanceHelper} from "../helpers/BalanceHelper.sol";
import {CreditFacadeTestHelper} from "../helpers/CreditFacadeTestHelper.sol";
import "../../lib/constants.sol";
import {BalanceHelper} from "../../helpers/BalanceHelper.sol";
import {CreditFacadeTestHelper} from "../../helpers/CreditFacadeTestHelper.sol";

// EXCEPTIONS
import "../../interfaces/IExceptions.sol";
import "../../../interfaces/IExceptions.sol";

// MOCKS
import {AdapterMock} from "../mocks/adapters/AdapterMock.sol";
import {AdapterMock} from "../../mocks/adapters/AdapterMock.sol";
import {TargetContractMock} from "@gearbox-protocol/core-v2/contracts/test/mocks/adapters/TargetContractMock.sol";

// SUITES
import {TokensTestSuite} from "../suites/TokensTestSuite.sol";
import {Tokens} from "../config/Tokens.sol";
import {CreditFacadeTestSuite} from "../suites/CreditFacadeTestSuite.sol";
import {CreditConfig} from "../config/CreditConfig.sol";
import {TokensTestSuite} from "../../suites/TokensTestSuite.sol";
import {Tokens} from "../../config/Tokens.sol";
import {CreditFacadeTestSuite} from "../../suites/CreditFacadeTestSuite.sol";
import {CreditConfig} from "../../config/CreditConfig.sol";

// EXCEPTIONS
import "../../interfaces/IExceptions.sol";
import "../../../interfaces/IExceptions.sol";

uint256 constant WETH_TEST_AMOUNT = 5 * WAD;
uint16 constant REFERRAL_CODE = 23;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
pragma solidity ^0.8.10;

import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {CreditFacadeV3} from "../../credit/CreditFacadeV3.sol";
import {CreditManagerV3} from "../../credit/CreditManagerV3.sol";
import {CreditConfigurator, CreditManagerOpts, CollateralToken} from "../../credit/CreditConfigurator.sol";
import {ICreditManagerV2, ICreditManagerV2Events} from "../../interfaces/ICreditManagerV2.sol";
import {ICreditConfiguratorEvents} from "../../interfaces/ICreditConfigurator.sol";
import {CreditFacadeV3} from "../../../credit/CreditFacadeV3.sol";
import {CreditManagerV3} from "../../../credit/CreditManagerV3.sol";
import {CreditConfigurator, CreditManagerOpts, CollateralToken} from "../../../credit/CreditConfigurator.sol";
import {ICreditManagerV2, ICreditManagerV2Events} from "../../../interfaces/ICreditManagerV2.sol";
import {ICreditConfiguratorEvents} from "../../../interfaces/ICreditConfigurator.sol";
import {IAdapter} from "@gearbox-protocol/core-v2/contracts/interfaces/adapters/IAdapter.sol";

import {BotList} from "../../support/BotList.sol";
import {BotList} from "../../../support/BotList.sol";

//
import {PERCENTAGE_FACTOR} from "@gearbox-protocol/core-v2/contracts/libraries/PercentageMath.sol";
Expand All @@ -20,22 +20,22 @@ import {AddressList} from "@gearbox-protocol/core-v2/contracts/libraries/Address

// EXCEPTIONS

import "../../interfaces/IExceptions.sol";
import "../../../interfaces/IExceptions.sol";

// TEST
import "../lib/constants.sol";
import "../../lib/constants.sol";

// MOCKS
import {AdapterMock} from "../mocks/adapters/AdapterMock.sol";
import {AdapterMock} from "../../mocks/adapters/AdapterMock.sol";
import {TargetContractMock} from "@gearbox-protocol/core-v2/contracts/test/mocks/adapters/TargetContractMock.sol";

// SUITES
import {TokensTestSuite} from "../suites/TokensTestSuite.sol";
import {Tokens} from "../config/Tokens.sol";
import {CreditFacadeTestSuite} from "../suites/CreditFacadeTestSuite.sol";
import {CreditConfig} from "../config/CreditConfig.sol";
import {TokensTestSuite} from "../../suites/TokensTestSuite.sol";
import {Tokens} from "../../config/Tokens.sol";
import {CreditFacadeTestSuite} from "../../suites/CreditFacadeTestSuite.sol";
import {CreditConfig} from "../../config/CreditConfig.sol";

import {CollateralTokensItem} from "../config/CreditConfig.sol";
import {CollateralTokensItem} from "../../config/CreditConfig.sol";

/// @title CreditConfiguratorTest
/// @notice Designed for unit test purposes only
Expand Down
Loading

0 comments on commit 68c5668

Please sign in to comment.