pragma solidity ^0.8.13;
import {Test, console2} from "forge-std/Test.sol";
import {CapitalPool} from "../src/core/CapitalPool.sol";
import {TokenManager} from "../src/core/TokenManager.sol";
import {MockPreMarkets} from "./mocks/MockPreMarkets.sol";
import {TadleFactory} from "../src/factory/TadleFactory.sol";
import {TokenBalanceType, ITokenManager} from "../src/interfaces/ITokenManager.sol";
import {MockERC20Token} from "./mocks/MockERC20Token.sol";
import {WETH9} from "./mocks/WETH9.sol";
contract TokenManagerTest is Test {
CapitalPool capitalPool;
TokenManager tokenManager;
MockPreMarkets preMarkets;
WETH9 weth9;
MockERC20Token mockUSDCToken;
uint256 constant USDC_AMOUNT = 100 * 10 ** 18;
address owner = address(this);
address user1 = address(1);
address user2 = address(2);
bytes4 private constant INITIALIZE_OWNERSHIP_SELECTOR =
bytes4(keccak256(bytes("initializeOwnership(address)")));
function setUp() public {
TadleFactory tadleFactory = new TadleFactory(owner);
weth9 = new WETH9();
mockUSDCToken = new MockERC20Token();
CapitalPool capitalPoolLogic = new CapitalPool();
TokenManager tokenManagerLogic = new TokenManager();
MockPreMarkets preMarketsLogic = new MockPreMarkets();
bytes memory deploy_data = abi.encodeWithSelector(
INITIALIZE_OWNERSHIP_SELECTOR,
owner
);
vm.startPrank(owner);
address preMarketsProxy = tadleFactory.deployUpgradeableProxy(
2,
address(preMarketsLogic),
bytes(deploy_data)
);
address capitalPoolProxy = tadleFactory.deployUpgradeableProxy(
4,
address(capitalPoolLogic),
bytes(deploy_data)
);
address tokenManagerProxy = tadleFactory.deployUpgradeableProxy(
5,
address(tokenManagerLogic),
bytes(deploy_data)
);
vm.stopPrank();
capitalPool = CapitalPool(capitalPoolProxy);
tokenManager = TokenManager(tokenManagerProxy);
preMarkets = MockPreMarkets(preMarketsProxy);
vm.startPrank(owner);
tokenManager.initialize(address(weth9));
address[] memory tokenAddressList = new address[](2);
tokenAddressList[0] = address(mockUSDCToken);
tokenAddressList[1] = address(weth9);
tokenManager.updateTokenWhiteListed(tokenAddressList, true);
vm.stopPrank();
deal(address(mockUSDCToken), user1, USDC_AMOUNT);
deal(address(mockUSDCToken), user2, USDC_AMOUNT);
vm.warp(1719826275);
vm.prank(user1);
mockUSDCToken.approve(address(tokenManager), type(uint256).max);
vm.prank(user2);
mockUSDCToken.approve(address(tokenManager), type(uint256).max);
capitalPool.approve(address(mockUSDCToken));
}
function test_withdrawAllUSDCFromPool() public {
address usdcAddress = address(mockUSDCToken);
TokenBalanceType balanceType = TokenBalanceType.MakerRefund;
vm.startPrank(user1);
preMarkets.tillIn(usdcAddress, USDC_AMOUNT);
preMarkets.addTokenBalance(usdcAddress, USDC_AMOUNT);
vm.stopPrank();
vm.startPrank(user2);
preMarkets.tillIn(usdcAddress, USDC_AMOUNT);
preMarkets.addTokenBalance(usdcAddress, USDC_AMOUNT);
vm.stopPrank();
assertEq(mockUSDCToken.balanceOf(user1), 0);
assertEq(mockUSDCToken.balanceOf(user2), 0);
assertEq(mockUSDCToken.balanceOf(address(capitalPool)), USDC_AMOUNT * 2);
assertEq(tokenManager.userTokenBalanceMap(user1, usdcAddress, balanceType), USDC_AMOUNT);
assertEq(tokenManager.userTokenBalanceMap(user2, usdcAddress, balanceType), USDC_AMOUNT);
vm.startPrank(user1);
tokenManager.withdraw(usdcAddress, balanceType);
tokenManager.withdraw(usdcAddress, balanceType);
vm.stopPrank();
assertEq(mockUSDCToken.balanceOf(user1), USDC_AMOUNT * 2);
assertEq(mockUSDCToken.balanceOf(user2), 0);
assertEq(mockUSDCToken.balanceOf(address(capitalPool)), 0);
assertEq(tokenManager.userTokenBalanceMap(user1, usdcAddress, balanceType), USDC_AMOUNT);
assertEq(tokenManager.userTokenBalanceMap(user2, usdcAddress, balanceType), USDC_AMOUNT);
}
}
pragma solidity ^0.8.13;
import {PerMarketsStorage} from "../../src/storage/PerMarketsStorage.sol";
import {ITadleFactory} from "../../src/factory/ITadleFactory.sol";
import {ITokenManager, TokenBalanceType} from "../../src/interfaces/ITokenManager.sol";
import {IWrappedNativeToken} from "../../src/interfaces/IWrappedNativeToken.sol";
import {Rescuable} from "../../src/utils/Rescuable.sol";
import {Related} from "../../src/utils/Related.sol";
import {RelatedContractLibraries} from "../../src/libraries/RelatedContractLibraries.sol";
contract MockPreMarkets is PerMarketsStorage, Rescuable, Related {
using RelatedContractLibraries for ITadleFactory;
constructor() Rescuable() {}
function tillIn(address _tokenAddress, uint256 _amount) external payable {
ITokenManager tokenManager = tadleFactory.getTokenManager();
tokenManager.tillIn{value: msg.value}(
_msgSender(),
_tokenAddress,
_amount,
false
);
}
function addTokenBalance(address _tokenAddress, uint256 _amount) external {
ITokenManager tokenManager = tadleFactory.getTokenManager();
tokenManager.addTokenBalance(
TokenBalanceType.MakerRefund,
_msgSender(),
_tokenAddress,
_amount
);
}
}