low level vulnerablity

Use .call instead of .transfer to send ether .transfer will relay 2300 gas and .call will relay all the gas. If the receive/fallback function from the recipient proxy contract has complex logic, using .transfer will fail, causing integration issues.
Unbounded loop
1
2
3
4
5
6
7
8
9
10
11
function claimGovFees() public {
address[] memory assets = bondNFT.getAssets();

for (uint i=0; i < assets.length; i++) {
uint balanceBefore = IERC20(assets[i]).balanceOf(address(this));
IGovNFT(govNFT).claim(assets[i]);
uint balanceAfter = IERC20(assets[i]).balanceOf(address(this));
IERC20(assets[i]).approve(address(bondNFT), type(uint256).max);
bondNFT.distribute(assets[i], balanceAfter - balanceBefore);
}
}
Use time units directly
1
uint constant private DAY = 24 * 60 * 60;
Chainlink price feed is not sufficiently validated and can return stale price
1
2
3
(uint80 roundId, int256 assetChainlinkPriceInt, , uint256 updatedAt, uint80 answeredInRound) = IPrice(_chainlinkFeed).latestRoundData();
require(answeredInRound >= roundId, "price is stale");
require(updatedAt > 0, "round is incomplete");
  • Use the safe variant and ERC721.mint
  • Add an event for critical parameter changes
  • Declare interfaces on separate files
  • Constants should be upper case
  • Replace constant private with private constant

Comments