Unpredictable behavior due to front running or general bad timing  Pending
In a number of cases, administrators of contracts can update or upgrade things in the system without warning. This has the potential to violate a security goal of the system.\\nSpecifically, privileged roles could use front running to make malicious changes just ahead of incoming transactions, or purely accidental negative effects could occur due to unfortunate timing of changes.\\nSome instances of this are more important than others, but in general users of the system should have assurances about the behavior of the action they're about to take.\\nThe deployer of the `PerpetualGovernance`, `AMMGovernance`, and `GlobalConfig` contracts are set as administrators for the contracts through `WhitelistedRole`. The `WhitelistedAdminRole` can whitelist other accounts at any time and allow them to perform actions protected by the `onlyWhitelisted` decorator.\\nUpdating governance and global configuration parameters are not protected by a time-lock and take effect immediately. This, therefore, creates an opportunity for administrators to front-run users on the exchange by changing parameters for orders. It may also allow an administrator to temporarily lift restrictions for themselves (e.g. withdrawalLockBlockCount).\\n`GlobalConfig`\\n`withdrawalLockBlockCount` is queried when applying for withdrawal. This value can be set zero enabling allowing immediate withdrawal.\\n`brokerLockBlockCount` is queried when setting a new broker. This value can e set to zero effectively enabling immediate broker changes.\\n```\\nfunction setGlobalParameter(bytes32 key, uint256 value) public onlyWhitelistAdmin {\\n    if (key == "withdrawalLockBlockCount") {\\n        withdrawalLockBlockCount = value;\\n    } else if (key == "brokerLockBlockCount") {\\n        brokerLockBlockCount = value;\\n    } else {\\n        revert("key not exists");\\n    }\\n    emit UpdateGlobalParameter(key, value);\\n}\\n```\\n\\n`PerpetualGovernance`\\ne.g. Admin can front-run specific `matchOrder` calls and set arbitrary dev fees or curve parameters…\\n```\\nfunction setGovernanceParameter(bytes32 key, int256 value) public onlyWhitelistAdmin {\\n    if (key == "initialMarginRate") {\\n        governance.initialMarginRate = value.toUint256();\\n        require(governance.initialMarginRate > 0, "require im > 0");\\n        require(governance.initialMarginRate < 10\\*\\*18, "require im < 1");\\n        require(governance.maintenanceMarginRate < governance.initialMarginRate, "require mm < im");\\n    } else if (key == "maintenanceMarginRate") {\\n        governance.maintenanceMarginRate = value.toUint256();\\n        require(governance.maintenanceMarginRate > 0, "require mm > 0");\\n        require(governance.maintenanceMarginRate < governance.initialMarginRate, "require mm < im");\\n        require(governance.liquidationPenaltyRate < governance.maintenanceMarginRate, "require lpr < mm");\\n        require(governance.penaltyFundRate < governance.maintenanceMarginRate, "require pfr < mm");\\n    } else if (key == "liquidationPenaltyRate") {\\n        governance.liquidationPenaltyRate = value.toUint256();\\n        require(governance.liquidationPenaltyRate < governance.maintenanceMarginRate, "require lpr < mm");\\n    } else if (key == "penaltyFundRate") {\\n        governance.penaltyFundRate = value.toUint256();\\n        require(governance.penaltyFundRate < governance.maintenanceMarginRate, "require pfr < mm");\\n    } else if (key == "takerDevFeeRate") {\\n        governance.takerDevFeeRate = value;\\n    } else if (key == "makerDevFeeRate") {\\n        governance.makerDevFeeRate = value;\\n    } else if (key == "lotSize") {\\n        require(\\n            governance.tradingLotSize == 0 || governance.tradingLotSize.mod(value.toUint256()) == 0,\\n            "require tls % ls == 0"\\n        );\\n        governance.lotSize = value.toUint256();\\n    } else if (key == "tradingLotSize") {\\n        require(governance.lotSize == 0 || value.toUint256().mod(governance.lotSize) == 0, "require tls % ls == 0");\\n        governance.tradingLotSize = value.toUint256();\\n    } else if (key == "longSocialLossPerContracts") {\\n        require(status == LibTypes.Status.SETTLING, "wrong perpetual status");\\n        socialLossPerContracts[uint256(LibTypes.Side.LONG)] = value;\\n    } else if (key == "shortSocialLossPerContracts") {\\n        require(status == LibTypes.Status.SETTLING, "wrong perpetual status");\\n        socialLossPerContracts[uint256(LibTypes.Side.SHORT)] = value;\\n    } else {\\n        revert("key not exists");\\n    }\\n    emit UpdateGovernanceParameter(key, value);\\n}\\n```\\n\\nAdmin can set `devAddress` or even update to a new `amm` and `globalConfig`\\n```\\nfunction setGovernanceAddress(bytes32 key, address value) public onlyWhitelistAdmin {\\n    require(value != address(0x0), "invalid address");\\n    if (key == "dev") {\\n        devAddress = value;\\n    } else if (key == "amm") {\\n        amm = IAMM(value);\\n    } else if (key == "globalConfig") {\\n        globalConfig = IGlobalConfig(value);\\n    } else {\\n        revert("key not exists");\\n    }\\n    emit UpdateGovernanceAddress(key, value);\\n}\\n```\\n\\n`AMMGovernance`\\n```\\nfunction setGovernanceParameter(bytes32 key, int256 value) public onlyWhitelistAdmin {\\n    if (key == "poolFeeRate") {\\n        governance.poolFeeRate = value.toUint256();\\n    } else if (key == "poolDevFeeRate") {\\n        governance.poolDevFeeRate = value.toUint256();\\n    } else if (key == "emaAlpha") {\\n        require(value > 0, "alpha should be > 0");\\n        governance.emaAlpha = value;\\n        emaAlpha2 = 10\\*\\*18 - governance.emaAlpha;\\n        emaAlpha2Ln = emaAlpha2.wln();\\n    } else if (key == "updatePremiumPrize") {\\n        governance.updatePremiumPrize = value.toUint256();\\n    } else if (key == "markPremiumLimit") {\\n        governance.markPremiumLimit = value;\\n    } else if (key == "fundingDampener") {\\n        governance.fundingDampener = value;\\n    } else {\\n        revert("key not exists");\\n    }\\n    emit UpdateGovernanceParameter(key, value);\\n}\\n```\\n
The underlying issue is that users of the system can't be sure what the behavior of a function call will be, and this is because the behavior can change at any time.\\nWe recommend giving the user advance notice of changes with a time lock. For example, make all updates to system parameters or upgrades require two steps with a mandatory time window between them. The first step merely broadcasts to users that a particular change is coming, and the second step commits that change after a suitable waiting period.\\nAdditionally, users should verify the whitelist setup before using the contract system and monitor it for new additions to the whitelist. Documentation should clearly outline what roles are owned by whom to support suitability. Sane parameter bounds should be enforced (e.g. min. disallow block delay of zero )
```\\nfunction setGlobalParameter(bytes32 key, uint256 value) public onlyWhitelistAdmin {\\n    if (key == "withdrawalLockBlockCount") {\\n        withdrawalLockBlockCount = value;\\n    } else if (key == "brokerLockBlockCount") {\\n        brokerLockBlockCount = value;\\n    } else {\\n        revert("key not exists");\\n    }\\n    emit UpdateGlobalParameter(key, value);\\n}\\n```\\n