function deposit(uint256 assets, address receiver) public override returns (uint256) {
uint256 fee = _getParticipationFee(assets);
@> uint256 stakeAsset = assets - fee;
@> stakedAsset[receiver] = stakeAsset;
}
function cancelParticipation () public {
@> uint256 refundAmount = stakedAsset[msg.sender];
stakedAsset[msg.sender] = 0;
uint256 shares = balanceOf(msg.sender);
_burn(msg.sender, shares);
@> IERC20(asset()).safeTransfer(msg.sender, refundAmount);
}
function test_CancelParticipation_FeeLoss() public {
vm.startPrank(user1);
mockToken.approve(address(briVault), 10 ether);
uint256 depositAmount = 5 ether;
uint256 expectedFee = (depositAmount * briVault.participationFeeBsp()) / 10000;
uint256 expectedStake = depositAmount - expectedFee;
uint256 userBalanceBefore = mockToken.balanceOf(user1);
briVault.deposit(depositAmount, user1);
briVault.cancelParticipation();
uint256 userBalanceAfterCancel = mockToken.balanceOf(user1)
uint256 totalUserSpent = userBalanceBefore - userBalanceAfterCancel;
assertEq(totalUserSpent, expectedFee, "User permanently loses participation fee");
vm.stopPrank();
}
+ mapping(address => uint256) public userFeesPaid;
+ uint256 public totalStaked;
function deposit(uint256 assets, address receiver) public override returns (uint256) {
// ... existing validation ...
uint256 fee = _getParticipationFee(assets);
uint256 stakeAsset = assets - fee;
stakedAsset[receiver] += stakeAsset;
+ userFeesPaid[receiver] += fee; // Track fee separately
+ totalStaked += stakeAsset;
- IERC20(asset()).safeTransferFrom(msg.sender, participationFeeAddress, fee);
- IERC20(asset()).safeTransferFrom(msg.sender, address(this), stakeAsset);
// Hold fee in contract instead of sending immediately
+ IERC20(asset()).safeTransferFrom(msg.sender, address(this), assets);
_mint(msg.sender, participantShares);
}
function cancelParticipation() public {
if (block.timestamp >= eventStartDate){
revert eventStarted();
}
uint256 refundAmount = stakedAsset[msg.sender];
+ uint256 feeRefund = userFeesPaid[msg.sender];
stakedAsset[msg.sender] = 0;
+ userFeesPaid[msg.sender] = 0;
+ totalStaked -= refundAmount;
uint256 shares = balanceOf(msg.sender);
_burn(msg.sender, shares);
- IERC20(asset()).safeTransfer(msg.sender, refundAmount);
// Refund BOTH stake AND fee
+ IERC20(asset()).safeTransfer(msg.sender, refundAmount + feeRefund);
}
+function transferFeesToFeeAddress() external onlyOwner {
+ // After event starts, transfer collected fees
+ if (block.timestamp < eventStartDate){
+ revert eventNotStarted();
+ }
+ uint256 feesCollected = address(this).balance - totalStaked;
+ IERC20(asset()).safeTransfer(participationFeeAddress, feesCollected);
+}