Vulnerability Details
The StabilityPool contract is missing critical logic for distributing RAAC tokens to managers based on their allocations.This is done through the depositRAACFromPoolfunction. But the function is lacking the distribution logic and is currently not called in LendingPool.
* @notice Deposits RAAC tokens from the liquidity pool.
* @param amount Amount of RAAC tokens to deposit.
*/
function depositRAACFromPool(uint256 amount) external onlyLiquidityPool validAmount(amount) {
uint256 preBalance = raacToken.balanceOf(address(this));
raacToken.safeTransferFrom(msg.sender, address(this), amount);
uint256 postBalance = raacToken.balanceOf(address(this));
if (postBalance != preBalance + amount) revert InvalidTransfer();
emit RAACDepositedFromPool(msg.sender, amount);
}
This breaks a core functionality of the protocol where managers should be rewarded based on their allocations for managing funds across different markets.
We can see from the docs that the StabilityPool is meant to distribute RAAC tokens to managers based on their allocations according to the docs:
Impact
Managers cannot receive their allocated RAAC token rewards.
There is no way to trigger the distribution even if the logic was implemented.
Recommendations
Add a distribution logic to depositRAACFromPool and call it from the LendingPool.
// StabilityPool
function depositRAACFromPool(uint256 amount) external onlyLiquidityPool validAmount(amount) {
uint256 preBalance = raacToken.balanceOf(address(this));
raacToken.safeTransferFrom(msg.sender, address(this), amount);
uint256 postBalance = raacToken.balanceOf(address(this));
if (postBalance != preBalance + amount) revert InvalidTransfer();
- // TODO: Logic for distributing to managers based on allocation
+ // Distribute RAAC to managers based on their allocations
+ if (totalAllocation > 0) {
+ for (uint256 i = 0; i < managerList.length; i++) {
+ address manager = managerList[i];
+ if (managerAllocation[manager] > 0) {
+ uint256 managerShare = (amount * managerAllocation[manager]) / totalAllocation;
+ if (managerShare > 0) {
+ raacToken.safeTransfer(manager, managerShare);
+ emit RAACDistributedToManager(manager, managerShare);
+ }
+ }
+ }
+ }
}
// LendindPool
+ function distributeManagerRewards(uint256 amount) external onlyOwner {
+ raacToken.approve(address(stabilityPool), amount);
+ stabilityPool.depositRAACFromPool(amount);
+ }