The Standard

The Standard
DeFiHardhat
20,000 USDC
View results
Submission Details
Severity: low
Invalid

Lack of Events for State Changes

Description

There is a lack of events emitted when changing the state in various contracts:

  • SmartVaultManagerV5 lacks events for important state changes.

  • SmartVaultV3's swap function doesn't emit an event for the swap action.

  • No event is emitted when the native token is transferred in SmartVaultV3, LiquidationPoolManager, and LiquidationPool.

  • LiquidationPoolManager::setFeePoolRate doesn't emit an event when changing the percentage.

  • LiquidationPool doesn't notify when there is a change in positions and pendingStakes.

Impact

The absence of events makes crucial information unavailable off-chain. This information is essential for monitoring and users to make informed decisions.

Recommended Mitigation

Add events for state changes in the affected contracts. Examples are provided below:

SmartVaultManagerV5.sol
+ event MintFeeRateUpdated(uint256 indexed rate);
+ event BurnFeeRateUpdated(uint256 indexed rate);
+ event SwapFeeRateUpdated(uint256 indexed rate);
+ event WethAddressUpdated(address indexed weth);
+ event SwapRouterAddressUpdated(address indexed swapRouter);
+ event NFTMetadataGeneratorAddressUpdated(address indexed nftMetadataGenerator);
+ event SmartVaultDeployerAddressUpdated(address indexed smartVaultDeployer);
+ event ProtocolAddressUpdated(address indexed protocol);
+ event LiquidationPoolManagerAddressUpdated(address indexed liquidator);
.
.
.
function setMintFeeRate(uint256 _rate) external onlyOwner {
mintFeeRate = _rate;
+ emit MintFeeRateUpdated(_rate);
}
function setBurnFeeRate(uint256 _rate) external onlyOwner {
burnFeeRate = _rate;
+ emit BurnFeeRateUpdated(_rate);
}
function setSwapFeeRate(uint256 _rate) external onlyOwner {
swapFeeRate = _rate;
+ emit SwapFeeRateUpdated(_rate);
}
function setWethAddress(address _weth) external onlyOwner {
weth = _weth;
+ emit WethAddressUpdated(_weth);
}
function setSwapRouter2(address _swapRouter) external onlyOwner {
swapRouter2 = _swapRouter;
+ emit SwapRouterAddressUpdated(_swapRouter);
}
function setNFTMetadataGenerator(
address _nftMetadataGenerator
) external onlyOwner {
nftMetadataGenerator = _nftMetadataGenerator;
+ emit NFTMetadataGeneratorAddressUpdated(_nftMetadataGenerator);
}
function setSmartVaultDeployer(
address _smartVaultDeployer
) external onlyOwner {
smartVaultDeployer = _smartVaultDeployer;
+ emit SmartVaultDeployerAddressUpdated(_smartVaultDeployer);
}
function setProtocolAddress(address _protocol) external onlyOwner {
protocol = _protocol;
+ emit ProtocolAddressUpdated(_protocol);
}
function setLiquidatorAddress(address _liquidator) external onlyOwner {
liquidator = _liquidator;
+ emit LiquidationPoolManagerAddressUpdated(_liquidator);
}
SmartVaultV3.sol
+ event TransferNative(address indexed _address, uint256 indexed balance);
+ event TokenSwapped(bytes32 indexed _inToken, bytes32 indexed _outToken, uint256 indexed _amount);
.
.
.
function liquidateNative() private {
if (address(this).balance != 0) {
+ address _protocol = payable(ISmartVaultManagerV3(manager).protocol()
+ uint256 balance = address(this).balance;
- (bool sent, ) = payable(ISmartVaultManagerV3(manager).protocol())
- .call{value: address(this).balance}("");
+ (bool sent, ) = _protocol.call{value: address(this).balance}("");
require(sent, "err-native-liquidate");
+ emit TransferNative(protocol, balance);
}
}
.
.
.
function swap(
bytes32 _inToken,
bytes32 _outToken,
uint256 _amount
) external onlyOwner {
+ emit TokenSwapped(_inToken, _outToken, _amount);
.
.
.
}
LiquidationPoolManager.sol
+ event TransferNative(address indexed _address, uint256 indexed balance);
+ event PoolFeePercentageUpdated(uint32 indexed poolFeePercentage);
.
.
.
function forwardRemainingRewards(
ITokenManager.Token[] memory _tokens
) private {
// e parcours tous les tokens
for (uint256 i = 0; i < _tokens.length; i++) {
.
.
.
if (_token.addr == address(0)) {
uint256 balance = address(this).balance;
if (balance > 0) {
(bool _sent, ) = protocol.call{value: balance}("");
require(_sent);
+ emit TransferNative(protocol, balance);
}
} else {
uint256 balance = IERC20(_token.addr).balanceOf(address(this));
if (balance > 0)
IERC20(_token.addr).transfer(protocol, balance);
}
}
}
.
.
.
function setPoolFeePercentage(
uint32 _poolFeePercentage
) external onlyOwner {
poolFeePercentage = _poolFeePercentage;
+ emit PoolFeePercentageUpdated(_poolFeePercentage);
}
LiquidationPool
+ event TransferNative(address indexed _address, uint256 indexed balance);
+ event PositionIncreased(address indexed holder, uint256 indexed EUROsAmount, uint256 indexed TSTAmount);
+ event PendingStakeCreated(address indexed holder, uint256 indexed TSTAmount, uint256 indexed EUROsAmount);
+ event PositionDeleted(address indexed holder);
function consolidatePendingStakes() private {
uint256 deadline = block.timestamp - 1 days;
for (int256 i = 0; uint256(i) < pendingStakes.length; i++) {
PendingStake memory _stake = pendingStakes[uint256(i)];
if (_stake.createdAt < deadline) {
positions[_stake.holder].holder = _stake.holder;
positions[_stake.holder].TST += _stake.TST;
positions[_stake.holder].EUROs += _stake.EUROs;
deletePendingStake(uint256(i));
+ emit PositionIncreased(_stake.holder, _stake.TST, _stake.EUROs);
// pause iterating on loop because there has been a deletion. "next" item has same index
i--;
}
}
}
// e semble appeler par un user pour déposer dans la pool et stake
function increasePosition(uint256 _tstVal, uint256 _eurosVal) external {
.
.
.
pendingStakes.push(
PendingStake(msg.sender, block.timestamp, _tstVal, _eurosVal)
);
+ emit PendingStakeCreated(msg.sender, _tstVal, _eurosVal);
addUniqueHolder(msg.sender);
}
.
.
.
function deletePosition(Position memory _position) private {
deleteHolder(_position.holder);
delete positions[_position.holder];
+ emit PositionDeleted(_position.holder);
}
.
.
.
function returnUnpurchasedNative(
ILiquidationPoolManager.Asset[] memory _assets,
uint256 _nativePurchased
) private {
// e parcours tous les assets en PARAMETRE
for (uint256 i = 0; i < _assets.length; i++) {
if (
_assets[i].token.addr == address(0) &&
_assets[i].token.symbol != bytes32(0)
) {
(bool _sent, ) = manager.call{
value: _assets[i].amount - _nativePurchased
}("");
require(_sent);
+ emit TransferNative(manager, amount - _nativePurchased);
}
}
}
Updates

Lead Judging Commences

hrishibhat Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

events

informational/invalid

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.