Summary
Various core functions such as depawsitMeowllateral()
, whiskdrawMeowllateral()
, meowintKittyCoin()
, burnKittyCoin()
, purrgeBadPawsition()
and meownufactureKittyVault()
is missing emit event. This does not provide enough transparency and there will be difficulties during security debugging and auditing.
Vulnerability Details
These functions are missing emit event
function depawsitMeowllateral(address _token, uint256 _ameownt) external tokenExists(_token) {
IKittyVault(tokenToVault[_token]).executeDepawsit(msg.sender, _ameownt);
}
function whiskdrawMeowllateral(address _token, uint256 _ameownt) external tokenExists(_token) {
IKittyVault(tokenToVault[_token]).executeWhiskdrawal(msg.sender, _ameownt);
require(_hasEnoughMeowllateral(msg.sender), KittyPool__NotEnoughMeowllateralPurrrr());
}
function meowintKittyCoin(uint256 _ameownt) external {
kittyCoinMeownted[msg.sender] += _ameownt;
i_kittyCoin.mint(msg.sender, _ameownt);
require(_hasEnoughMeowllateral(msg.sender), KittyPool__NotEnoughMeowllateralPurrrr());
}
function burnKittyCoin(address _onBehalfOf, uint256 _ameownt) external {
kittyCoinMeownted[_onBehalfOf] -= _ameownt;
i_kittyCoin.burn(msg.sender, _ameownt);
}
function purrgeBadPawsition(address _user) external returns (uint256 _totalAmountReceived) {
require(!(_hasEnoughMeowllateral(_user)), KittyPool__UserIsPurrfect());
uint256 totalDebt = kittyCoinMeownted[_user];
kittyCoinMeownted[_user] = 0;
i_kittyCoin.burn(msg.sender, totalDebt);
uint256 userMeowllateralInEuros = getUserMeowllateralInEuros(_user);
uint256 redeemPercent;
if (totalDebt >= userMeowllateralInEuros) {
redeemPercent = PRECISION;
}
else {
redeemPercent = totalDebt.mulDiv(PRECISION, userMeowllateralInEuros);
}
uint256 vaults_length = vaults.length;
for (uint256 i; i < vaults_length; ) {
IKittyVault _vault = IKittyVault(vaults[i]);
uint256 vaultCollateral = _vault.getUserVaultMeowllateralInEuros(_user);
uint256 toDistribute = vaultCollateral.mulDiv(redeemPercent, PRECISION);
uint256 extraCollateral = vaultCollateral - toDistribute;
uint256 extraReward = toDistribute.mulDiv(REWARD_PERCENT, PRECISION);
extraReward = Math.min(extraReward, extraCollateral);
_totalAmountReceived += (toDistribute + extraReward);
_vault.executeWhiskdrawal(msg.sender, toDistribute + extraReward);
unchecked {
++i;
}
}
}
function meownufactureKittyVault(address _token, address _priceFeed) external onlyMeowntainer {
require(tokenToVault[_token] == address(0), KittyPool__TokenAlreadyExistsMeeoooww());
address _kittyVault = address(new KittyVault{ salt: bytes32(abi.encodePacked(ERC20(_token).symbol())) }(_token, address(this), _priceFeed, i_euroPriceFeed, meowntainer, i_aavePool));
tokenToVault[_token] = _kittyVault;
vaults.push(_kittyVault);
}
Impact
The absence of events in key functions of the KittyPool contract undermines the ability to track and audit critical operations, such as minting, burning, depositing, and withdrawing collateral. This lack of visibility can hinder effective monitoring, make debugging challenging, and reduce transparency, potentially leading to difficulties in verifying contract activity and ensuring accountability.
Tools Used
Foundry
Recommendations
Define the events and emit those events when the core functions are performed.
// Define events
+ event MeowllateralDeposited(address indexed user, address indexed token, uint256 amount);
+ event MeowllateralWithdrawn(address indexed user, address indexed token, uint256 amount);
+ event KittyCoinMinted(address indexed user, uint256 amount);
+ event KittyCoinBurned(address indexed user, uint256 amount);
+ event BadDebtLiquidated(address indexed user, uint256 totalAmountReceived);
+ event VaultCreated(address indexed token, address indexed vault);
// Emit events in the relevant functions
function depawsitMeowllateral(address _token, uint256 _ameownt) external tokenExists(_token) {
// existing code...
+ emit MeowllateralDeposited(msg.sender, _token, _ameownt);
}
function whiskdrawMeowllateral(address _token, uint256 _ameownt) external tokenExists(_token) {
// existing code...
+ emit MeowllateralWithdrawn(msg.sender, _token, _ameownt);
}
function meowintKittyCoin(uint256 _ameownt) external {
// existing code...
+ emit KittyCoinMinted(msg.sender, _ameownt);
}
function burnKittyCoin(address _onBehalfOf, uint256 _ameownt) external {
// existing code...
+ emit KittyCoinBurned(_onBehalfOf, _ameownt);
}
function purrgeBadPawsition(address _user) external returns (uint256 _totalAmountReceived) {
// existing codes...
+ emit BadDebtLiquidated(_user, _totalAmountReceived);
}
function meownufactureKittyVault(address _token, address _priceFeed) external onlyMeowntainer {
// existing codes...
+ emit VaultCreated(_token, _kittyVault);
}