Summary
Code for the modifier is copied by the compiler inside the function that is using the modifier.
Vulnerability Details
The code from the modifier is copied inside each function by the compiler. If the code inside the modifier is very large and some functions are using the modifier then the deployment would cost more gas.
for example this if condition would be copied inside each function that is using this modifier
modifier moreThanZero(uint256 amount) {
if (amount == 0) {
revert DSCEngine__NeedsMoreThanZero();
}
_;
}
function someFunction(){
}
Impact
This would cost some extra gas for the contract deployment.
Tests done on the Remix IDE for getting the gas cost:
// Deployment result without functions for modifiers
DSC:
gas 1983209 gas
transaction cost 1725071 gas
execution cost 1546645 gas
DSCEngine:
gas 2090752 gas
transaction cost 1818629 gas
execution cost 1630629 gas
OracleLibrary:
gas 356176 gas
transaction cost 309798 gas
execution cost 238306 gas
// Deployment with functions for modifiers:
DSC:
gas 1983209 gas
transaction cost 1725071 gas
execution cost 1546645 gas
DSCEngine:
gas 2049552 gas
transaction cost 1782791 gas
execution cost 1596187 gas
OracleLibrary:
gas 356176 gas
transaction cost 309798 gas
execution cost 238306 gas
As we can see if we use the special functions for checking the modifier code then it would cost less gas.
Tools Used
Foundry test, remix ide
Recommendations
consider using this:
modifier moreThanZero(uint256 amount) {
_checkIsZero(amount);
_;
}
modifier isAllowedToken(address token) {
_isAllowedToken(token);
_;
}
function _checkIsZero(uint256 amount) internal pure {
if (amount == 0) {
revert DSCEngine__NeedsMoreThanZero();
}
}
function _isAllowedToken(address token) internal view{
if (s_priceFeeds[token] == address(0)) {
revert DSCEngine__NotAllowedToken();
}
}
By using the above way, only these line would be copied down inside the functions