First Flight #21: KittyFi

First Flight #21
Beginner FriendlyDeFiFoundry
100 EXP
View results
Submission Details
Severity: medium
Invalid

Deterministic Address and Token Symbol Conflict in `KittyPool::meownufactureKittyVault`

Summary

The KittyPool::meownufactureKittyVault function in KittyPool.sol is used to create a new KittyVault contract. The address of the new vault is generated deterministically using the salt parameter, which is based on the token symbol. This approach has two significant issues:

  1. The address of the vault can be known before its creation, potentially exposing the contract to front-running attacks, while this is an unlikely attack vector it is worth a mention.

  2. Tokens with the same symbol cannot be deployed, potentially leading to conflicts and failures in contract creation.

Vulnerability Details

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

  • Deterministic address generation can lead to front-running attacks, where an attacker could anticipate the creation of a vault and take advantage of this knowledge.

  • Token symbol conflicts can prevent the deployment of multiple tokens with the same symbol, limiting the contract's functionality and flexibility.

Tools Used

Manual review, Aderyn.

Recommendations

Use a different method for generating the salt value that does not rely solely on the token symbol. Ideally the function could be modified to take salt as an argument but simply using a combination of the token address or a nonce could ensure uniqueness and prevent symbol conflicts.
Example:

function meownufactureKittyVault(address _token, address _priceFeed, uint256 _extraSalt) external onlyMeowntainer {
require(tokenToVault[_token] == address(0), KittyPool__TokenAlreadyExistsMeeoooww());
address _kittyVault = address(new KittyVault{ salt: bytes32(abi.encodePacked(ERC20(_token).symbol(), _extraSalt)) }(_token, address(this), _priceFeed, i_euroPriceFeed, meowntainer, i_aavePool));
tokenToVault[_token] = _kittyVault;
vaults.push(_kittyVault);
}

Reference

OpenZeppelin - Deploying with create2

Updates

Lead Judging Commences

shikhar229169 Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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