Summary
The meownufactureKittyVault()
function in the KittyPool contract does not check if the vault length has exceeded the limit of 20, which is stated in the contract assumptions.
Vulnerability Details
This function does not check if the vault length has exceeded the limit of 20.
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
In this PoC, we simply add more than 20 tokens types into the vault
function vaultsLength() public view returns (uint256) {
return vaults.length;
}
function test_VaultExceeds20Length() public {
for (uint256 i = 0; i < 21; i++) {
vm.startPrank(meowntainer);
ERC20Mock token = new ERC20Mock();
MockV3Aggregator priceFeed = new MockV3Aggregator(8, 1e8);
kittyPool.meownufactureKittyVault(address(token), address(priceFeed));
}
uint256 length = kittyPool.vaultsLength();
console.log("length: ", length);
}
Result
Ran 1 test for test/KittyFiTest.t.sol:KittyFiTest
[PASS] test_VaultExceeds20Length() (gas: 36596661)
Logs:
length: 22
Traces:
........
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 54.03s (46.38s CPU time)
Ran 1 test suite in 55.47s (54.03s CPU time): 1 tests passed, 0 failed, 0 skipped (1 total tests)
Tools Used
Foundry
Recommendations
Add a constraint check to ensure that the no more than 20 collateral tokens will be used in the protocol.
function meownufactureKittyVault(address _token, address _priceFeed) external onlyMeowntainer {
require(tokenToVault[_token] == address(0), KittyPool__TokenAlreadyExistsMeeoooww());
+ require(vaults.length <= 20, "Maximum number of vaults reached");
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);
}