DeFiFoundry
60,000 USDC
View results
Submission Details
Severity: low
Invalid

Incomplete Input Validation in `GlobalConfigurationBranch::createPerpMarket`

Summary

The GlobalConfigurationBranch::createPerpMarket function has incomplete input validation for critical components of the params argument. Specifically, it lacks checks for the keeper address in SettlementConfiguration.Data and the makerFee and takerFee in OrderFees.Data. This oversight means

  1. A zero address could be set as the keeper in the SettlementConfiguration, potentially breaking keeper-dependent functionalities.

  2. Zero Input values could be passed as takerFee and makerFee, risking economic imbalances in the market.

Vulnerability Details

1.) Missing Zero Address Check: The keeper address in SettlementConfiguration.Data is not checked for a zero address. This check is absent in GlobalConfigurationBranch::createPerpMarket function, PerpMarket::create function and the SettlementConfiguration::update function.

https://github.com/Cyfrin/2024-07-zaros/blob/main/src/perpetuals/branches/GlobalConfigurationBranch.sol#L379-L441
https://github.com/Cyfrin/2024-07-zaros/blob/main/src/perpetuals/leaves/PerpMarket.sol#L395-L429
https://github.com/Cyfrin/2024-07-zaros/blob/main/src/perpetuals/leaves/SettlementConfiguration.sol#L109-L123

function update(
uint128 marketId,
uint128 settlementConfigurationId,
Data memory settlementConfiguration
) internal {
// ...
self.keeper = settlementConfiguration.keeper; // No zero address check
// ...
}

2.) Incomplete Validation for OrderFees: The orderFees parameter, which contains makerFee and takerFee, is not validated for zero values in the createPerpMarket function.

function createPerpMarket(CreatePerpMarketParams calldata params) external onlyOwner {
if (params.marketId == 0) {
revert Errors.ZeroInput("marketId");
}
if (abi.encodePacked(params.name).length == 0) {
revert Errors.ZeroInput("name");
}
if (abi.encodePacked(params.symbol).length == 0) {
revert Errors.ZeroInput("symbol");
}
if (params.priceAdapter == address(0)) {
revert Errors.ZeroInput("priceAdapter");
}
if (params.maintenanceMarginRateX18 == 0) {
revert Errors.ZeroInput("maintenanceMarginRateX18");
}
if (params.maxOpenInterest == 0) {
revert Errors.ZeroInput("maxOpenInterest");
}
if (params.maxSkew == 0) {
revert Errors.ZeroInput("maxSkew");
}
if (params.initialMarginRateX18 <= params.maintenanceMarginRateX18) {
revert Errors.InitialMarginRateLessOrEqualThanMaintenanceMarginRate();
}
if (params.skewScale == 0) {
revert Errors.ZeroInput("skewScale");
}
if (params.minTradeSizeX18 == 0) {
revert Errors.ZeroInput("minTradeSizeX18");
}
if (params.maxFundingVelocity == 0) {
revert Errors.ZeroInput("maxFundingVelocity");
}
if (params.priceFeedHeartbeatSeconds == 0) {
revert Errors.ZeroInput("priceFeedHeartbeatSeconds");
}
// Missing validation for keeper address and order fees
}

Impact

  • A zero address for the keeper could lead to failed transactions or inability to execute critical functions relying on the keeper.

  • Zero values for makerFee or takerFee might result in economic imbalances in the market or potential exploitation of fee mechanisms.

Tools Used

Manual Review

Recommendations

1). Add Zero Address Check for Keeper: Ensure that the keeper address in SettlementConfiguration.Data is checked to confirm it is not a zero address by adding this line of code below:

if (params.marketOrderConfiguration.keeper == address(0)) {
revert Errors.ZeroInput("keeper");
}
if (params.offchainOrdersConfiguration.keeper == address(0)) {
revert Errors.ZeroInput("keeper");
}

2). Validate Order Fees: Include checks to ensure makerFee and takerFee are greater than zero by adding this line of code below:

if (params.orderFees.makerFee == 0) {
revert Errors.ZeroInput("makerFee");
}
if (params.orderFees.takerFee == 0) {
revert Errors.ZeroInput("takerFee");
}

the GlobalConfigurationBranch::createPerpMarket could be updated to:

function createPerpMarket(CreatePerpMarketParams calldata params) external onlyOwner {
if (params.marketId == 0) {
revert Errors.ZeroInput("marketId");
}
if (abi.encodePacked(params.name).length == 0) {
revert Errors.ZeroInput("name");
}
if (abi.encodePacked(params.symbol).length == 0) {
revert Errors.ZeroInput("symbol");
}
if (params.priceAdapter == address(0)) {
revert Errors.ZeroInput("priceAdapter");
}
if (params.maintenanceMarginRateX18 == 0) {
revert Errors.ZeroInput("maintenanceMarginRateX18");
}
if (params.maxOpenInterest == 0) {
revert Errors.ZeroInput("maxOpenInterest");
}
if (params.maxSkew == 0) {
revert Errors.ZeroInput("maxSkew");
}
if (params.initialMarginRateX18 <= params.maintenanceMarginRateX18) {
revert Errors.InitialMarginRateLessOrEqualThanMaintenanceMarginRate();
}
if (params.skewScale == 0) {
revert Errors.ZeroInput("skewScale");
}
if (params.minTradeSizeX18 == 0) {
revert Errors.ZeroInput("minTradeSizeX18");
}
if (params.maxFundingVelocity == 0) {
revert Errors.ZeroInput("maxFundingVelocity");
}
if (params.priceFeedHeartbeatSeconds == 0) {
revert Errors.ZeroInput("priceFeedHeartbeatSeconds");
}
// Check for zero address on the keeper
if (params.marketOrderConfiguration.keeper == address(0)) {
revert Errors.ZeroInput("keeper");
}
if (params.offchainOrdersConfiguration.keeper == address(0)) {
revert Errors.ZeroInput("keeper");
}
// Check for zero input on fee
if (params.orderFees.makerFee == 0) {
revert Errors.ZeroInput("makerFee");
}
if (params.orderFees.takerFee == 0) {
revert Errors.ZeroInput("takerFee");
}
// rest of function
}
Updates

Lead Judging Commences

inallhonesty Lead Judge
about 1 year ago
inallhonesty 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.