user logout in the vault changed to queuing mechanism, and add function of batch sending WUSD
This commit is contained in:
514
test/Vault.t.sol
514
test/Vault.t.sol
@@ -50,6 +50,9 @@ contract VaultTest is Test {
|
||||
event AssetsDeposited(uint256 amount);
|
||||
event HardCapSet(uint256 newHardCap);
|
||||
event NextRedemptionTimeSet(uint256 newRedemptionTime);
|
||||
event WithdrawRequestCreated(uint256 indexed requestId, address indexed user, uint256 ytAmount, uint256 wusdAmount, uint256 queueIndex);
|
||||
event WithdrawRequestProcessed(uint256 indexed requestId, address indexed user, uint256 wusdAmount);
|
||||
event BatchProcessed(uint256 startIndex, uint256 endIndex, uint256 processedCount, uint256 totalWusdDistributed);
|
||||
|
||||
function setUp() public {
|
||||
// 设置测试账户
|
||||
@@ -346,24 +349,35 @@ contract VaultTest is Test {
|
||||
// 快进到赎回时间之后
|
||||
vm.warp(vault.nextRedemptionTime() + 1);
|
||||
|
||||
// 提款
|
||||
// 提交提现请求
|
||||
uint256 withdrawAmount = 500 * 1e18; // 提取500 YT
|
||||
uint256 expectedWusd = 500 * 1e18; // 价格1:1,获得500 WUSD
|
||||
|
||||
uint256 user1WusdBefore = wusd.balanceOf(user1);
|
||||
|
||||
vm.startPrank(user1);
|
||||
vm.expectEmit(true, false, false, true);
|
||||
emit Sell(user1, withdrawAmount, expectedWusd);
|
||||
vm.expectEmit(true, true, false, true);
|
||||
emit WithdrawRequestCreated(0, user1, withdrawAmount, expectedWusd, 0);
|
||||
|
||||
uint256 wusdReceived = vault.withdrawYT(withdrawAmount);
|
||||
uint256 requestId = vault.withdrawYT(withdrawAmount);
|
||||
vm.stopPrank();
|
||||
|
||||
// 验证结果
|
||||
assertEq(wusdReceived, expectedWusd);
|
||||
assertEq(vault.balanceOf(user1), depositAmount - withdrawAmount);
|
||||
// 验证请求创建
|
||||
assertEq(requestId, 0);
|
||||
assertEq(vault.balanceOf(user1), depositAmount - withdrawAmount); // YT已销毁
|
||||
assertEq(vault.totalSupply(), depositAmount - withdrawAmount);
|
||||
assertEq(wusd.balanceOf(user1), user1WusdBefore + expectedWusd);
|
||||
assertEq(wusd.balanceOf(user1), user1WusdBefore); // WUSD还未发放
|
||||
assertEq(vault.pendingRequestsCount(), 1);
|
||||
|
||||
// 批量处理提现请求
|
||||
vm.prank(manager);
|
||||
(uint256 processedCount, uint256 totalDistributed) = vault.processBatchWithdrawals(10);
|
||||
|
||||
// 验证结果
|
||||
assertEq(processedCount, 1);
|
||||
assertEq(totalDistributed, expectedWusd);
|
||||
assertEq(wusd.balanceOf(user1), user1WusdBefore + expectedWusd); // 现在收到了WUSD
|
||||
assertEq(vault.pendingRequestsCount(), 0);
|
||||
}
|
||||
|
||||
function test_14_WithdrawYTWithDifferentPrices() public {
|
||||
@@ -386,17 +400,26 @@ contract VaultTest is Test {
|
||||
// 快进到赎回时间
|
||||
vm.warp(vault.nextRedemptionTime() + 1);
|
||||
|
||||
// 提款500 YT
|
||||
// 提交提现请求
|
||||
uint256 withdrawAmount = 500 * 1e18;
|
||||
// wusdAmount = 500 * 1.05 / 0.98 = 535.714285714285714285 WUSD
|
||||
uint256 expectedWusd = (withdrawAmount * 1050000000000000000000000000000) / 980000000000000000000000000000;
|
||||
|
||||
uint256 user1BalanceBefore = wusd.balanceOf(user1);
|
||||
|
||||
vm.startPrank(user1);
|
||||
uint256 wusdReceived = vault.withdrawYT(withdrawAmount);
|
||||
uint256 requestId = vault.withdrawYT(withdrawAmount);
|
||||
vm.stopPrank();
|
||||
|
||||
assertEq(wusdReceived, expectedWusd);
|
||||
assertEq(wusdReceived, 535714285714285714285); // 约535.71 WUSD
|
||||
assertEq(requestId, 0);
|
||||
|
||||
// 批量处理
|
||||
vm.prank(manager);
|
||||
vault.processBatchWithdrawals(10);
|
||||
|
||||
// 验证用户收到的WUSD(余额增加量)
|
||||
assertEq(wusd.balanceOf(user1), user1BalanceBefore + expectedWusd);
|
||||
assertEq(expectedWusd, 535714285714285714285); // 约535.71 WUSD
|
||||
}
|
||||
|
||||
function test_15_CannotWithdrawBeforeRedemptionTime() public {
|
||||
@@ -440,7 +463,7 @@ contract VaultTest is Test {
|
||||
vm.stopPrank();
|
||||
}
|
||||
|
||||
function test_18_CannotWithdrawWhenInsufficientWUSD() public {
|
||||
function test_18_CannotProcessWhenInsufficientWUSD() public {
|
||||
vault = _createVault();
|
||||
|
||||
// User1存款
|
||||
@@ -456,11 +479,33 @@ contract VaultTest is Test {
|
||||
// 快进到赎回时间
|
||||
vm.warp(vault.nextRedemptionTime() + 1);
|
||||
|
||||
// User1尝试提款,但vault中没有WUSD
|
||||
// User1可以提交提现请求(即使vault中没有WUSD)
|
||||
vm.startPrank(user1);
|
||||
vm.expectRevert(YTAssetVault.InsufficientWUSD.selector);
|
||||
vault.withdrawYT(500 * 1e18);
|
||||
uint256 requestId = vault.withdrawYT(500 * 1e18);
|
||||
vm.stopPrank();
|
||||
|
||||
assertEq(requestId, 0);
|
||||
assertEq(vault.pendingRequestsCount(), 1);
|
||||
|
||||
// 但是批量处理时会因为资金不足而处理0个请求
|
||||
vm.prank(manager);
|
||||
(uint256 processedCount, ) = vault.processBatchWithdrawals(10);
|
||||
|
||||
assertEq(processedCount, 0); // 没有处理任何请求
|
||||
assertEq(vault.pendingRequestsCount(), 1); // 请求仍在队列中
|
||||
|
||||
// Manager归还资金后可以处理
|
||||
vm.startPrank(manager);
|
||||
wusd.approve(address(vault), 1000 * 1e18);
|
||||
vault.depositManagedAssets(1000 * 1e18);
|
||||
vm.stopPrank();
|
||||
|
||||
// 现在可以处理了
|
||||
vm.prank(manager);
|
||||
(uint256 processedCount2, ) = vault.processBatchWithdrawals(10);
|
||||
|
||||
assertEq(processedCount2, 1);
|
||||
assertEq(vault.pendingRequestsCount(), 0);
|
||||
}
|
||||
|
||||
function test_19_UpdatePrices() public {
|
||||
@@ -895,18 +940,25 @@ contract VaultTest is Test {
|
||||
// 6. 快进到赎回时间
|
||||
vm.warp(vault.nextRedemptionTime() + 1);
|
||||
|
||||
// 7. User1提取部分YT
|
||||
// 7. User1提交提现请求
|
||||
uint256 user1YtBalance = vault.balanceOf(user1);
|
||||
uint256 withdrawYtAmount = 5000 * 1e18;
|
||||
uint256 user1WusdBefore = wusd.balanceOf(user1);
|
||||
|
||||
vm.startPrank(user1);
|
||||
uint256 wusdReceived = vault.withdrawYT(withdrawYtAmount);
|
||||
uint256 requestId = vault.withdrawYT(withdrawYtAmount);
|
||||
vm.stopPrank();
|
||||
|
||||
assertEq(requestId, 0);
|
||||
|
||||
// 8. 批量处理提现
|
||||
vm.prank(manager);
|
||||
vault.processBatchWithdrawals(10);
|
||||
|
||||
// 按新价格计算: 5000 * 1.10 / 1.05 = 5238.095238095238095238 WUSD
|
||||
uint256 expectedWusd = (withdrawYtAmount * 1100000000000000000000000000000) / 1050000000000000000000000000000;
|
||||
assertEq(wusdReceived, expectedWusd);
|
||||
assertEq(wusdReceived, 5238095238095238095238);
|
||||
assertEq(wusd.balanceOf(user1), user1WusdBefore + expectedWusd);
|
||||
assertEq(expectedWusd, 5238095238095238095238);
|
||||
|
||||
// 验证最终状态
|
||||
assertEq(vault.balanceOf(user1), user1YtBalance - withdrawYtAmount);
|
||||
@@ -950,22 +1002,32 @@ contract VaultTest is Test {
|
||||
// 快进到赎回时间
|
||||
vm.warp(vault.nextRedemptionTime() + 1);
|
||||
|
||||
// User1提取
|
||||
uint256 user1WusdBefore = wusd.balanceOf(user1);
|
||||
uint256 user2WusdBefore = wusd.balanceOf(user2);
|
||||
|
||||
// User1提交提现请求
|
||||
vm.startPrank(user1);
|
||||
uint256 wusdBack1 = vault.withdrawYT(ytReceived1);
|
||||
uint256 requestId1 = vault.withdrawYT(ytReceived1);
|
||||
vm.stopPrank();
|
||||
|
||||
// User2提交提现请求
|
||||
vm.startPrank(user2);
|
||||
uint256 requestId2 = vault.withdrawYT(ytReceived2);
|
||||
vm.stopPrank();
|
||||
|
||||
assertEq(requestId1, 0);
|
||||
assertEq(requestId2, 1);
|
||||
|
||||
// 批量处理所有请求
|
||||
vm.prank(manager);
|
||||
vault.processBatchWithdrawals(10);
|
||||
|
||||
// wusdAmount = 10000 * 0.90 / 0.95 = 9473.684210526315789473
|
||||
assertEq(wusdBack1, 9473684210526315789473);
|
||||
|
||||
// User2提取
|
||||
vm.startPrank(user2);
|
||||
uint256 wusdBack2 = vault.withdrawYT(ytReceived2);
|
||||
vm.stopPrank();
|
||||
assertEq(wusd.balanceOf(user1), user1WusdBefore + 9473684210526315789473);
|
||||
|
||||
// wusdAmount = 9166.666... * 0.90 / 0.95 = 8684.210526315789473684
|
||||
// 允许1 wei的舍入误差
|
||||
assertApproxEqAbs(wusdBack2, 8684210526315789473684, 1);
|
||||
assertApproxEqAbs(wusd.balanceOf(user2), user2WusdBefore + 8684210526315789473684, 1);
|
||||
}
|
||||
|
||||
// ==================== 暂停功能测试 ====================
|
||||
@@ -1037,20 +1099,28 @@ contract VaultTest is Test {
|
||||
// 暂停vault
|
||||
factory.pauseVault(address(vault));
|
||||
|
||||
// 尝试提款应该失败
|
||||
// 尝试提交提现请求应该失败
|
||||
vm.startPrank(user1);
|
||||
vm.expectRevert(abi.encodeWithSignature("EnforcedPause()"));
|
||||
vault.withdrawYT(500 * 1e18);
|
||||
vm.stopPrank();
|
||||
|
||||
// 恢复后应该可以提款
|
||||
// 恢复后应该可以提交请求和处理
|
||||
factory.unpauseVault(address(vault));
|
||||
|
||||
uint256 user1WusdBefore = wusd.balanceOf(user1);
|
||||
|
||||
vm.startPrank(user1);
|
||||
uint256 wusdReceived = vault.withdrawYT(500 * 1e18);
|
||||
uint256 requestId = vault.withdrawYT(500 * 1e18);
|
||||
vm.stopPrank();
|
||||
|
||||
assertEq(wusdReceived, 500 * 1e18, "withdraw should work after unpause");
|
||||
assertEq(requestId, 0);
|
||||
|
||||
// 批量处理
|
||||
vm.prank(manager);
|
||||
vault.processBatchWithdrawals(10);
|
||||
|
||||
assertEq(wusd.balanceOf(user1), user1WusdBefore + 500 * 1e18, "withdraw should work after unpause");
|
||||
}
|
||||
|
||||
function test_45_CannotWithdrawForManagementWhenPaused() public {
|
||||
@@ -1150,4 +1220,382 @@ contract VaultTest is Test {
|
||||
assertEq(totalAssets, 1000 * 1e18, "getVaultInfo should work");
|
||||
assertEq(idleAssets, 1000 * 1e18, "getVaultInfo should work");
|
||||
}
|
||||
|
||||
// ==================== 排队提现机制测试 ====================
|
||||
|
||||
function test_48_WithdrawQueueBasic() public {
|
||||
vault = _createVault();
|
||||
|
||||
// User1和User2存款
|
||||
vm.startPrank(user1);
|
||||
wusd.approve(address(vault), 1000 * 1e18);
|
||||
vault.depositYT(1000 * 1e18);
|
||||
vm.stopPrank();
|
||||
|
||||
vm.startPrank(user2);
|
||||
wusd.approve(address(vault), 2000 * 1e18);
|
||||
vault.depositYT(2000 * 1e18);
|
||||
vm.stopPrank();
|
||||
|
||||
// 快进到赎回时间
|
||||
vm.warp(vault.nextRedemptionTime() + 1);
|
||||
|
||||
// User1先提交请求
|
||||
vm.prank(user1);
|
||||
uint256 requestId1 = vault.withdrawYT(500 * 1e18);
|
||||
|
||||
// User2后提交请求
|
||||
vm.prank(user2);
|
||||
uint256 requestId2 = vault.withdrawYT(1000 * 1e18);
|
||||
|
||||
assertEq(requestId1, 0);
|
||||
assertEq(requestId2, 1);
|
||||
assertEq(vault.pendingRequestsCount(), 2);
|
||||
|
||||
// 查询队列进度
|
||||
(uint256 currentIndex, uint256 totalRequests, uint256 pendingRequests) = vault.getQueueProgress();
|
||||
assertEq(currentIndex, 0);
|
||||
assertEq(totalRequests, 2);
|
||||
assertEq(pendingRequests, 2);
|
||||
}
|
||||
|
||||
function test_49_ProcessBatchWithdrawals() public {
|
||||
vault = _createVault();
|
||||
|
||||
// 3个用户存款
|
||||
vm.startPrank(user1);
|
||||
wusd.approve(address(vault), 1000 * 1e18);
|
||||
vault.depositYT(1000 * 1e18);
|
||||
vm.stopPrank();
|
||||
|
||||
vm.startPrank(user2);
|
||||
wusd.approve(address(vault), 2000 * 1e18);
|
||||
vault.depositYT(2000 * 1e18);
|
||||
vm.stopPrank();
|
||||
|
||||
address user3 = makeAddr("user3");
|
||||
wusd.transfer(user3, 3000 * 1e18);
|
||||
vm.startPrank(user3);
|
||||
wusd.approve(address(vault), 3000 * 1e18);
|
||||
vault.depositYT(3000 * 1e18);
|
||||
vm.stopPrank();
|
||||
|
||||
// 快进到赎回时间
|
||||
vm.warp(vault.nextRedemptionTime() + 1);
|
||||
|
||||
uint256 user1WusdBefore = wusd.balanceOf(user1);
|
||||
uint256 user2WusdBefore = wusd.balanceOf(user2);
|
||||
uint256 user3WusdBefore = wusd.balanceOf(user3);
|
||||
|
||||
// 提交3个提现请求
|
||||
vm.prank(user1);
|
||||
vault.withdrawYT(500 * 1e18);
|
||||
|
||||
vm.prank(user2);
|
||||
vault.withdrawYT(1000 * 1e18);
|
||||
|
||||
vm.prank(user3);
|
||||
vault.withdrawYT(1500 * 1e18);
|
||||
|
||||
assertEq(vault.pendingRequestsCount(), 3);
|
||||
|
||||
// 批量处理所有请求
|
||||
vm.prank(manager);
|
||||
(uint256 processedCount, uint256 totalDistributed) = vault.processBatchWithdrawals(10);
|
||||
|
||||
assertEq(processedCount, 3);
|
||||
assertEq(totalDistributed, 3000 * 1e18);
|
||||
assertEq(vault.pendingRequestsCount(), 0);
|
||||
|
||||
// 验证用户收到WUSD
|
||||
assertEq(wusd.balanceOf(user1), user1WusdBefore + 500 * 1e18);
|
||||
assertEq(wusd.balanceOf(user2), user2WusdBefore + 1000 * 1e18);
|
||||
assertEq(wusd.balanceOf(user3), user3WusdBefore + 1500 * 1e18);
|
||||
}
|
||||
|
||||
function test_50_ProcessBatchWithLimit() public {
|
||||
vault = _createVault();
|
||||
|
||||
// 准备5个用户和请求
|
||||
address[] memory users = new address[](5);
|
||||
for (uint i = 0; i < 5; i++) {
|
||||
users[i] = makeAddr(string(abi.encodePacked("user", i)));
|
||||
wusd.transfer(users[i], 1000 * 1e18);
|
||||
|
||||
vm.startPrank(users[i]);
|
||||
wusd.approve(address(vault), 1000 * 1e18);
|
||||
vault.depositYT(1000 * 1e18);
|
||||
vm.stopPrank();
|
||||
}
|
||||
|
||||
// 快进到赎回时间
|
||||
vm.warp(vault.nextRedemptionTime() + 1);
|
||||
|
||||
// 提交5个提现请求
|
||||
for (uint i = 0; i < 5; i++) {
|
||||
vm.prank(users[i]);
|
||||
vault.withdrawYT(500 * 1e18);
|
||||
}
|
||||
|
||||
assertEq(vault.pendingRequestsCount(), 5);
|
||||
|
||||
// 第一次批量处理:只处理2个
|
||||
vm.prank(manager);
|
||||
(uint256 processedCount1, ) = vault.processBatchWithdrawals(2);
|
||||
|
||||
assertEq(processedCount1, 2);
|
||||
assertEq(vault.pendingRequestsCount(), 3);
|
||||
|
||||
// 第二次批量处理:处理剩余3个
|
||||
vm.prank(manager);
|
||||
(uint256 processedCount2, ) = vault.processBatchWithdrawals(10);
|
||||
|
||||
assertEq(processedCount2, 3);
|
||||
assertEq(vault.pendingRequestsCount(), 0);
|
||||
}
|
||||
|
||||
function test_51_ProcessStopsWhenInsufficientFunds() public {
|
||||
vault = _createVault();
|
||||
|
||||
// User1存款1000
|
||||
vm.startPrank(user1);
|
||||
wusd.approve(address(vault), 1000 * 1e18);
|
||||
vault.depositYT(1000 * 1e18);
|
||||
vm.stopPrank();
|
||||
|
||||
// User2存款2000
|
||||
vm.startPrank(user2);
|
||||
wusd.approve(address(vault), 2000 * 1e18);
|
||||
vault.depositYT(2000 * 1e18);
|
||||
vm.stopPrank();
|
||||
|
||||
// Manager提取大部分资金
|
||||
vm.prank(manager);
|
||||
vault.withdrawForManagement(manager, 2500 * 1e18);
|
||||
|
||||
// 现在vault只有500 WUSD
|
||||
assertEq(vault.idleAssets(), 500 * 1e18);
|
||||
|
||||
// 快进到赎回时间
|
||||
vm.warp(vault.nextRedemptionTime() + 1);
|
||||
|
||||
// 两个用户提交提现请求
|
||||
vm.prank(user1);
|
||||
vault.withdrawYT(1000 * 1e18); // 需要1000 WUSD
|
||||
|
||||
vm.prank(user2);
|
||||
vault.withdrawYT(2000 * 1e18); // 需要2000 WUSD
|
||||
|
||||
// 批量处理:只能处理第一个请求(500 WUSD不够)
|
||||
vm.prank(manager);
|
||||
(uint256 processedCount, ) = vault.processBatchWithdrawals(10);
|
||||
|
||||
assertEq(processedCount, 0); // 第一个请求需要1000,但只有500
|
||||
assertEq(vault.pendingRequestsCount(), 2);
|
||||
|
||||
// Manager归还资金
|
||||
vm.startPrank(manager);
|
||||
wusd.approve(address(vault), 2500 * 1e18);
|
||||
vault.depositManagedAssets(2500 * 1e18);
|
||||
vm.stopPrank();
|
||||
|
||||
// 现在可以处理所有请求
|
||||
vm.prank(manager);
|
||||
(uint256 processedCount2, ) = vault.processBatchWithdrawals(10);
|
||||
|
||||
assertEq(processedCount2, 2);
|
||||
assertEq(vault.pendingRequestsCount(), 0);
|
||||
}
|
||||
|
||||
function test_52_GetUserRequestIds() public {
|
||||
vault = _createVault();
|
||||
|
||||
// User1存款并提交多个请求
|
||||
vm.startPrank(user1);
|
||||
wusd.approve(address(vault), 3000 * 1e18);
|
||||
vault.depositYT(3000 * 1e18);
|
||||
vm.stopPrank();
|
||||
|
||||
vm.warp(vault.nextRedemptionTime() + 1);
|
||||
|
||||
vm.startPrank(user1);
|
||||
vault.withdrawYT(500 * 1e18);
|
||||
vault.withdrawYT(1000 * 1e18);
|
||||
vault.withdrawYT(500 * 1e18);
|
||||
vm.stopPrank();
|
||||
|
||||
// 查询用户的所有请求ID
|
||||
uint256[] memory userRequests = vault.getUserRequestIds(user1);
|
||||
assertEq(userRequests.length, 3);
|
||||
assertEq(userRequests[0], 0);
|
||||
assertEq(userRequests[1], 1);
|
||||
assertEq(userRequests[2], 2);
|
||||
}
|
||||
|
||||
function test_53_GetRequestDetails() public {
|
||||
vault = _createVault();
|
||||
|
||||
vm.startPrank(user1);
|
||||
wusd.approve(address(vault), 1000 * 1e18);
|
||||
vault.depositYT(1000 * 1e18);
|
||||
vm.stopPrank();
|
||||
|
||||
vm.warp(vault.nextRedemptionTime() + 1);
|
||||
|
||||
vm.prank(user1);
|
||||
uint256 requestId = vault.withdrawYT(500 * 1e18);
|
||||
|
||||
// 查询请求详情
|
||||
YTAssetVault.WithdrawRequest memory request = vault.getRequestDetails(requestId);
|
||||
|
||||
assertEq(request.user, user1);
|
||||
assertEq(request.ytAmount, 500 * 1e18);
|
||||
assertEq(request.wusdAmount, 500 * 1e18);
|
||||
assertEq(request.queueIndex, 0);
|
||||
assertFalse(request.processed);
|
||||
}
|
||||
|
||||
function test_54_GetUserPendingRequests() public {
|
||||
vault = _createVault();
|
||||
|
||||
vm.startPrank(user1);
|
||||
wusd.approve(address(vault), 3000 * 1e18);
|
||||
vault.depositYT(3000 * 1e18);
|
||||
vm.stopPrank();
|
||||
|
||||
vm.warp(vault.nextRedemptionTime() + 1);
|
||||
|
||||
// 提交3个请求
|
||||
vm.startPrank(user1);
|
||||
vault.withdrawYT(500 * 1e18);
|
||||
vault.withdrawYT(1000 * 1e18);
|
||||
vault.withdrawYT(500 * 1e18);
|
||||
vm.stopPrank();
|
||||
|
||||
// 查询待处理的请求
|
||||
YTAssetVault.WithdrawRequest[] memory pendingRequests = vault.getUserPendingRequests(user1);
|
||||
assertEq(pendingRequests.length, 3);
|
||||
|
||||
// 处理第一个请求
|
||||
vm.prank(manager);
|
||||
vault.processBatchWithdrawals(1);
|
||||
|
||||
// 再次查询
|
||||
YTAssetVault.WithdrawRequest[] memory pendingRequests2 = vault.getUserPendingRequests(user1);
|
||||
assertEq(pendingRequests2.length, 2);
|
||||
}
|
||||
|
||||
function test_55_FactoryCanProcessWithdrawals() public {
|
||||
vault = _createVault();
|
||||
|
||||
vm.startPrank(user1);
|
||||
wusd.approve(address(vault), 1000 * 1e18);
|
||||
vault.depositYT(1000 * 1e18);
|
||||
vm.stopPrank();
|
||||
|
||||
vm.warp(vault.nextRedemptionTime() + 1);
|
||||
|
||||
vm.prank(user1);
|
||||
vault.withdrawYT(500 * 1e18);
|
||||
|
||||
// Factory也可以调用processBatchWithdrawals
|
||||
vm.prank(address(factory));
|
||||
(uint256 processedCount, ) = vault.processBatchWithdrawals(10);
|
||||
|
||||
assertEq(processedCount, 1);
|
||||
}
|
||||
|
||||
function test_56_OnlyManagerOrFactoryCanProcess() public {
|
||||
vault = _createVault();
|
||||
|
||||
vm.startPrank(user1);
|
||||
wusd.approve(address(vault), 1000 * 1e18);
|
||||
vault.depositYT(1000 * 1e18);
|
||||
vm.stopPrank();
|
||||
|
||||
vm.warp(vault.nextRedemptionTime() + 1);
|
||||
|
||||
vm.prank(user1);
|
||||
vault.withdrawYT(500 * 1e18);
|
||||
|
||||
// 普通用户不能调用processBatchWithdrawals
|
||||
vm.prank(user2);
|
||||
vm.expectRevert(YTAssetVault.Forbidden.selector);
|
||||
vault.processBatchWithdrawals(10);
|
||||
}
|
||||
|
||||
function test_57_CannotProcessWithZeroBatchSize() public {
|
||||
vault = _createVault();
|
||||
|
||||
vm.prank(manager);
|
||||
vm.expectRevert(YTAssetVault.InvalidBatchSize.selector);
|
||||
vault.processBatchWithdrawals(0);
|
||||
}
|
||||
|
||||
function test_58_FIFOOrderGuarantee() public {
|
||||
vault = _createVault();
|
||||
|
||||
// 3个用户按顺序存款
|
||||
address user3 = makeAddr("user3");
|
||||
|
||||
vm.startPrank(user1);
|
||||
wusd.approve(address(vault), 1000 * 1e18);
|
||||
vault.depositYT(1000 * 1e18);
|
||||
vm.stopPrank();
|
||||
|
||||
vm.startPrank(user2);
|
||||
wusd.approve(address(vault), 1000 * 1e18);
|
||||
vault.depositYT(1000 * 1e18);
|
||||
vm.stopPrank();
|
||||
|
||||
wusd.transfer(user3, 1000 * 1e18);
|
||||
vm.startPrank(user3);
|
||||
wusd.approve(address(vault), 1000 * 1e18);
|
||||
vault.depositYT(1000 * 1e18);
|
||||
vm.stopPrank();
|
||||
|
||||
// Manager提取资金,只留下1500 WUSD
|
||||
vm.prank(manager);
|
||||
vault.withdrawForManagement(manager, 1500 * 1e18);
|
||||
|
||||
vm.warp(vault.nextRedemptionTime() + 1);
|
||||
|
||||
uint256 user1WusdBefore = wusd.balanceOf(user1);
|
||||
uint256 user2WusdBefore = wusd.balanceOf(user2);
|
||||
uint256 user3WusdBefore = wusd.balanceOf(user3);
|
||||
|
||||
// 按顺序提交请求
|
||||
vm.prank(user1);
|
||||
vault.withdrawYT(1000 * 1e18); // requestId = 0, 需要1000 WUSD
|
||||
|
||||
vm.prank(user2);
|
||||
vault.withdrawYT(1000 * 1e18); // requestId = 1, 需要1000 WUSD
|
||||
|
||||
vm.prank(user3);
|
||||
vault.withdrawYT(1000 * 1e18); // requestId = 2, 需要1000 WUSD
|
||||
|
||||
// 批量处理:只有1500 WUSD,应该按FIFO顺序处理
|
||||
vm.prank(manager);
|
||||
(uint256 processedCount, ) = vault.processBatchWithdrawals(10);
|
||||
|
||||
// 只能处理前1个(user1),第2个需要1000但只剩500
|
||||
assertEq(processedCount, 1);
|
||||
assertEq(wusd.balanceOf(user1), user1WusdBefore + 1000 * 1e18); // 已处理
|
||||
assertEq(wusd.balanceOf(user2), user2WusdBefore); // 未处理
|
||||
assertEq(wusd.balanceOf(user3), user3WusdBefore); // 未处理
|
||||
|
||||
// 归还资金后继续处理
|
||||
vm.startPrank(manager);
|
||||
wusd.approve(address(vault), 1500 * 1e18);
|
||||
vault.depositManagedAssets(1500 * 1e18);
|
||||
vm.stopPrank();
|
||||
|
||||
// 处理剩余请求
|
||||
vm.prank(manager);
|
||||
(uint256 processedCount2, ) = vault.processBatchWithdrawals(10);
|
||||
|
||||
assertEq(processedCount2, 2);
|
||||
assertEq(wusd.balanceOf(user2), user2WusdBefore + 1000 * 1e18); // 现在已处理
|
||||
assertEq(wusd.balanceOf(user3), user3WusdBefore + 1000 * 1e18); // 现在已处理
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user