msc-smart-contract-auditing/vulnerable-functions-base huggingface dataset:
Vulnerability: Unbounded loop when validating Merkle proofs
Severity: medium

Description:
It seems like the loop for validating Merkle proofs is unbounded. If possible it would be good to have an upper bound to prevent DoS-like attacks. It seems like the depth of the tree, and thus, the length of the proof could be bounded.\\nThis could also simplify the decoding and make it more robust. For instance, in `_decodeWithdrawalOperatorData` it is unclear what happens if the data length is not a multiple of 32. It seems like it might result in out-of-bound reads.\\n```\\nuint256 proofNb = (\\_operatorData.length - 84) / 32;\\nbytes32[] memory proof = new bytes32[](proofNb);\\nuint256 index = 0;\\nfor (uint256 i = 116; i <= \\_operatorData.length; i = i + 32) {\\n    bytes32 temp;\\n    assembly {\\n        temp := mload(add(\\_operatorData, i))\\n    }\\n    proof[index] = temp;\\n    index++;\\n}\\n```\\n

Impact:

Recommended mitigation:
Consider enforcing a bound on the length of Merkle proofs.\\nAlso note that if similar mitigation method as issue 5.1 is used, this method can be replaced by a simpler function using ABI Decode, which does not have any unbounded issues as the sizes of the hashes are fixed (or can be indicated in the passed objects)
Vulnerability: Mitigation for possible reentrancy in token transfers
Severity: medium

Description:
ERC777 adds significant features to the token implementation, however there are some known risks associated with this token, such as possible reentrancy attack vector. Given that the Amp token uses hooks to communicate to Collateral manager, it seems that the environment is trusted and safe. However, a minor modification to the implementation can result in safer implementation of the token transfer.\\n```\\nrequire(\\n    \\_balanceOfByPartition[\\_from][\\_fromPartition] >= \\_value,\\n    EC\\_52\\_INSUFFICIENT\\_BALANCE\\n);\\n\\nbytes32 toPartition = \\_fromPartition;\\nif (\\_data.length >= 64) {\\n    toPartition = \\_getDestinationPartition(\\_fromPartition, \\_data);\\n}\\n\\n\\_callPreTransferHooks(\\n    \\_fromPartition,\\n    \\_operator,\\n    \\_from,\\n    \\_to,\\n    \\_value,\\n    \\_data,\\n    \\_operatorData\\n);\\n\\n\\_removeTokenFromPartition(\\_from, \\_fromPartition, \\_value);\\n\\_transfer(\\_from, \\_to, \\_value);\\n\\_addTokenToPartition(\\_to, toPartition, \\_value);\\n\\n\\_callPostTransferHooks(\\n    toPartition,\\n```\\n

Impact:

Recommended mitigation:
It is suggested to move any condition check that is checking the balance to after the external call. However `_callPostTransferHooks` needs to be called after the state changes, so the suggested mitigation here is to move the require at line 1152 to after `_callPreTransferHooks()` function (e.g. line 1171).
Vulnerability: Potentially inconsistent input validation
Severity: medium

Description:
There are some functions that might require additional input validation (similar to other functions):\\nAmp.transferWithData: `require(_isOperator(msg.sender, _from), EC_58_INVALID_OPERATOR);` like in\\n```\\nrequire(\\_isOperator(msg.sender, \\_from), EC\\_58\\_INVALID\\_OPERATOR);\\n```\\n\\nAmp.authorizeOperatorByPartition: `require(_operator != msg.sender);` like in\\n```\\nrequire(\\_operator != msg.sender);\\n```\\n\\nAmp.revokeOperatorByPartition: `require(_operator != msg.sender);` like in\\n```\\nrequire(\\_operator != msg.sender);\\n```\\n

Impact:

Recommended mitigation:
Consider adding additional input validation.
Vulnerability: ERC20 compatibility of Amp token using defaultPartition
Severity: medium

Description:
It is somewhat unclear how the Amp token ensures ERC20 compatibility. While the `default` partition is used in some places (for instance, in function balanceOf) there are also separate fields for (aggregated) balances/allowances. This seems to introduce some redundancy and raises certain questions about when which fields are relevant.\\n`_allowed` is used in function `allowance` instead of `_allowedByPartition` with the default partition\\nAn `Approval` event should be emitted when approving the default partition\\n```\\nemit ApprovalByPartition(\\_partition, \\_tokenHolder, \\_spender, \\_amount);\\n```\\n\\n`increaseAllowance()` vs. `increaseAllowanceByPartition()`

Impact:

Recommended mitigation:
After the mid-audit discussion, it was clear that the general `balanceOf` method (with no partition) is not needed and can be replaced with a `balanceOf` function that returns balance of the default partition, similarly for allowance, the general `increaseAllowance` function can simply call `increaseAllowanceByPartition` using default partition (same for decreaseAllowance).
Vulnerability: Additional validation for canReceive
Severity: low

Description:
For `FlexaCollateralManager.tokensReceived` there is validation to ensure that only the Amp calls the function. In contrast, there is no such validation for `canReceive` and it is unclear if this is the intention.\\n```\\nrequire(msg.sender == amp, "Invalid sender");\\n```\\n

Impact:

Recommended mitigation:
Consider adding a conjunct `msg.sender == amp` in function `_canReceive`.\\n```\\nfunction \\_canReceive(address \\_to, bytes32 \\_destinationPartition) internal view returns (bool) {\\n    return \\_to == address(this) && partitions[\\_destinationPartition];\\n}\\n```\\n
Vulnerability: Discrepancy between code and comments
Severity: low

Description:
There are some discrepancies between (uncommented) code and the documentations comment:\\n```\\n// Indicate token verifies Amp, ERC777 and ERC20 interfaces\\nERC1820Implementer.\\_setInterface(AMP\\_INTERFACE\\_NAME);\\nERC1820Implementer.\\_setInterface(ERC20\\_INTERFACE\\_NAME);\\n// ERC1820Implementer.\\_setInterface(ERC777\\_INTERFACE\\_NAME);\\n```\\n\\n```\\n/\\*\\*\\n \\* @notice Indicates a supply refund was executed\\n \\* @param supplier Address whose refund authorization was executed\\n \\* @param partition Partition from which the tokens were transferred\\n \\* @param amount Amount of tokens transferred\\n \\*/\\nevent SupplyRefund(\\n    address indexed supplier,\\n    bytes32 indexed partition,\\n    uint256 amount,\\n    uint256 indexed nonce\\n);\\n```\\n

Impact:

Recommended mitigation:
Consider updating either the code or the comment.
Vulnerability: Several fields could potentially be private  Acknowledged
Severity: low

Description:
Several fields in `Amp` could possibly be private:\\nswapToken:\\n```\\nISwapToken public swapToken;\\n```\\n\\nswapTokenGraveyard:\\n```\\naddress public constant swapTokenGraveyard = 0x000000000000000000000000000000000000dEaD;\\n```\\n\\ncollateralManagers:\\n```\\naddress[] public collateralManagers;\\n```\\n\\npartitionStrategies:\\n```\\nbytes4[] public partitionStrategies;\\n```\\n\\nThe same hold for several fields in `FlexaCollateralManager`. For instance:\\npartitions:\\n```\\nmapping(bytes32 => bool) public partitions;\\n```\\n\\nnonceToSupply:\\n```\\nmapping(uint256 => Supply) public nonceToSupply;\\n```\\n\\nwithdrawalRootToNonce:\\n```\\nmapping(bytes32 => uint256) public withdrawalRootToNonce;\\n```\\n

Impact:

Recommended mitigation:
Double-check that you really want to expose those fields.
Vulnerability: Several fields could be declared immutable  Acknowledged
Severity: low

Description:
Several fields could be declared immutable to make clear that they never change after construction:\\nAmp._name:\\n```\\nstring internal \\_name;\\n```\\n\\nAmp._symbol:\\n```\\nstring internal \\_symbol;\\n```\\n\\nAmp.swapToken:\\n```\\nISwapToken public swapToken;\\n```\\n\\nFlexaCollateralManager.amp:\\n```\\naddress public amp;\\n```\\n

Impact:

Recommended mitigation:
Use the `immutable` annotation in Solidity (see Immutable).
Vulnerability: A reverting fallback function will lock up all payouts
Severity: high

Description:
```\\nfunction \\_transferETH(address \\_recipient, uint256 \\_amount) private {\\n    (bool success, ) = \\_recipient.call{value: \\_amount}(\\n        abi.encodeWithSignature("")\\n    );\\n    require(success, "Transfer Failed");\\n}\\n```\\n\\nThe `_payment()` function processes a list of transfers to settle the transactions in an `ExchangeBox`. If any of the recipients of an Eth transfer is a smart contract that reverts, then the entire payout will fail and will be unrecoverable.

Impact:

Recommended mitigation:
Implement a queuing mechanism to allow buyers/sellers to initiate the withdrawal on their own using a ‘pull-over-push pattern.'\\nIgnore a failed transfer and leave the responsibility up to users to receive them properly.
Vulnerability: Force traders to mint gas token
Severity: high

Description:
Attack scenario:\\nAlice makes a large trade via the Fairswap_iDOLvsEth exchange. This will tie up her iDOL until the box is executed.\\nMallory makes a small trades to buy ETH immediately afterwards, the trades are routed through an attack contract.\\nAlice needs to execute the box to get her iDOL out.\\nBecause the gas amount is unlimited, when you Mallory's ETH is paid out to her attack contract, mint a lot of GasToken.\\nIf Alice has $100 worth of ETH tied up in the exchange, you can basically ransom her for $99 of gas token or else she'll never see her funds again.\\n```\\nfunction \\_transferETH(address \\_recipient, uint256 \\_amount) private {\\n```\\n

Impact:

Recommended mitigation:
When sending ETH, a pull-payment model is generally preferable.\\nThis would require setting up a queue, allowing users to call a function to initiate a withdrawal.
Vulnerability: Missing Proper Access Control
Severity: high

Description:
Some functions do not have proper access control and are `public`, meaning that anyone can call them. This will result in system take over depending on how critical those functionalities are.\\n```\\n \\*/\\nfunction setIDOLContract(address contractAddress) public {\\n    require(address(\\_IDOLContract) == address(0), "IDOL contract is already registered");\\n    \\_setStableCoinContract(contractAddress);\\n}\\n```\\n

Impact:

Recommended mitigation:
Make the `setIDOLContract()` function `internal` and call it from the constructor, or only allow the `deployer` to set the value.
Vulnerability: Code is not production-ready
Severity: high

Description:
Similar to other discussed issues, several areas of the code suggest that the system is not production-ready. This results in narrow test scenarios that do not cover production code flow.\\nisNotStartedAuction\\ninAcceptingBidsPeriod\\ninRevealingValuationPeriod\\ninReceivingBidsPeriod\\n```\\n/\\*\\n// Indicates any auction has never held for a specified BondID\\nfunction isNotStartedAuction(bytes32 auctionID) public virtual override returns (bool) {\\n uint256 closingTime = \\_auctionClosingTime[auctionID];\\n return closingTime == 0;\\n}\\n\\n// Indicates if the auctionID is in bid acceptance status\\nfunction inAcceptingBidsPeriod(bytes32 auctionID) public virtual override returns (bool) {\\n uint256 closingTime = \\_auctionClosingTime[auctionID];\\n```\\n\\n```\\n// TEST\\nfunction isNotStartedAuction(bytes32 auctionID)\\n    public\\n    virtual\\n    override\\n    returns (bool)\\n{\\n    return true;\\n}\\n\\n// TEST\\nfunction inAcceptingBidsPeriod(bytes32 auctionID)\\n```\\n\\nThese commented-out functions contain essential functionality for the Auction contract. For example, `inRevealingValuationPeriod` is used to allow revealing of the bid price publicly:\\n```\\nrequire(\\n    inRevealingValuationPeriod(auctionID),\\n    "it is not the time to reveal the value of bids"\\n);\\n```\\n

Impact:

Recommended mitigation:
Remove the test functions and use the production code for testing. The tests must have full coverage of the production code to be considered complete.
Vulnerability: Unreachable code due to checked conditions
Severity: medium

Description:
```\\nfunction revealBid(\\n    bytes32 auctionID,\\n    uint256 price,\\n    uint256 targetSBTAmount,\\n    uint256 random\\n) public override {\\n    require(\\n        inRevealingValuationPeriod(auctionID),\\n        "it is not the time to reveal the value of bids"\\n    );\\n```\\n\\nHowever, later in the same function, code exists to introduce “Penalties for revealing too early.” This checks to see if the function was called before closing, which should not be possible given the previous check.\\n```\\n/\\*\\*\\n \\* @dev Penalties for revealing too early.\\n \\* Some participants may not follow the rule and publicate their bid information before the reveal process.\\n \\* In such a case, the bid price is overwritten by the bid with the strike price (slightly unfavored price).\\n \\*/\\nuint256 bidPrice = price;\\n\\n/\\*\\*\\n \\* @dev FOR TEST CODE RUNNING: The following if statement in L533 should be replaced by the comment out\\n \\*/\\nif (inAcceptingBidsPeriod(auctionID)) {\\n    // if (false) {\\n    (, , uint256 solidStrikePriceE4, ) = \\_getBondFromAuctionID(auctionID);\\n    bidPrice = \\_exchangeSBT2IDOL(solidStrikePriceE4.mul(10\\*\\*18));\\n}\\n```\\n

Impact:

Recommended mitigation:
Resolution\\nComment from Lien Protocol:\\nDouble-check the logic in these functions. If revealing should be allowed (but penalized in the earlier stage), the first check should be changed. However, based on our understanding, the first check is correct, and the second check for early reveal is redundant and should be removed.
Vulnerability: Fairswap: inconsistent checks on _executionOrder()
Severity: low

Description:
The `_executionOrder()` function should only be called under specific conditions. However, these conditions are not always consistently defined.\\n```\\nif (nextBoxNumber > 1 && nextBoxNumber > nextExecuteBoxNumber) {\\n```\\n\\n```\\nif (nextBoxNumber > 1 && nextBoxNumber > nextExecuteBoxNumber) {\\n```\\n\\n```\\nif (nextBoxNumber > 1 && nextBoxNumber >= nextExecuteBoxNumber) {\\n```\\n

Impact:

Recommended mitigation:
Resolution\\nComment from Lien Protocol:\\nReduce duplicate code by defining an internal function to perform this check. A clear, descriptive name will help to clarify the intention.
Vulnerability: Inconsistency in DecimalSafeMath implementations
Severity: low

Description:
There are two different implementations of `DecimalSafeMath` in the 3 FairSwap repositories.\\n```\\nlibrary DecimalSafeMath {\\n    function decimalDiv(uint256 a, uint256 b)internal pure returns (uint256) {\\n        // assert(b > 0); // Solidity automatically throws when dividing by 0\\n        uint256 a\\_ = a \\* 1000000000000000000;\\n        uint256 c = a\\_ / b;\\n        // assert(a == b \\* c + a % b); // There is no case in which this doesn't hold\\n        return c;\\n    }\\n```\\n\\n```\\nlibrary DecimalSafeMath {\\n\\n    function decimalDiv(uint256 a, uint256 b)internal pure returns (uint256) {\\n        // assert(b > 0); // Solidity automatically throws when dividing by 0\\n      \\n        uint256 c = (a \\* 1000000000000000000) / b;\\n        // assert(a == b \\* c + a % b); // There is no case in which this doesn't hold\\n        return c;\\n    }\\n```\\n

Impact:

Recommended mitigation:
Try removing duplicate code/libraries and using a better inheritance model to include one file in all FairSwaps.
Vulnerability: Exchange - CancelOrder has no effect  Pending
Severity: high

Description:
The exchange provides means for the `trader` or `broker` to cancel the order. The `cancelOrder` method, however, only stores the hash of the canceled order in mapping but the mapping is never checked. It is therefore effectively impossible for a `trader` to cancel an order.\\n```\\nfunction cancelOrder(LibOrder.Order memory order) public {\\n    require(msg.sender == order.trader || msg.sender == order.broker, "invalid caller");\\n\\n    bytes32 orderHash = order.getOrderHash();\\n    cancelled[orderHash] = true;\\n\\n    emit Cancel(orderHash);\\n}\\n```\\n

Impact:

Recommended mitigation:
`matchOrders*` or `validateOrderParam` should check if `cancelled[orderHash] == true` and abort fulfilling the order.\\nVerify the order params (Signature) before accepting it as canceled.
Vulnerability: Perpetual - withdraw should only be available in NORMAL state  Pending
Severity: high

Description:
According to the specification `withdraw` can only be called in `NORMAL` state. However, the implementation allows it to be called in `NORMAL` and `SETTLED` mode.\\nWithdraw only checks for `!SETTLING` state which resolves to `NORMAL` and `SETTLED`.\\n```\\nfunction withdraw(uint256 amount) public {\\n    withdrawFromAccount(msg.sender, amount);\\n}\\n```\\n\\n```\\nfunction withdrawFromAccount(address payable guy, uint256 amount) private {\\n    require(guy != address(0), "invalid guy");\\n    require(status != LibTypes.Status.SETTLING, "wrong perpetual status");\\n\\n    uint256 currentMarkPrice = markPrice();\\n    require(isSafeWithPrice(guy, currentMarkPrice), "unsafe before withdraw");\\n    remargin(guy, currentMarkPrice);\\n    address broker = currentBroker(guy);\\n    bool forced = broker == address(amm.perpetualProxy()) || broker == address(0);\\n    withdraw(guy, amount, forced);\\n\\n    require(isSafeWithPrice(guy, currentMarkPrice), "unsafe after withdraw");\\n    require(availableMarginWithPrice(guy, currentMarkPrice) >= 0, "withdraw margin");\\n}\\n```\\n\\nIn contrast, `withdrawFor` requires the state to be NORMAL:\\n```\\nfunction withdrawFor(address payable guy, uint256 amount) public onlyWhitelisted {\\n    require(status == LibTypes.Status.NORMAL, "wrong perpetual status");\\n    withdrawFromAccount(guy, amount);\\n}\\n```\\n

Impact:

Recommended mitigation:
Resolution\\nThis issue was resolved by requiring `status == LibTypes.Status.NORMAL`.\\n`withdraw` should only be available in the `NORMAL` operation mode.
Vulnerability: Perpetual - withdrawFromInsuranceFund should check wadAmount instead of rawAmount  Pending
Severity: high

Description:
`withdrawFromInsurance` checks that enough funds are in the insurance fund before allowing withdrawal by an admin by checking the provided `rawAmount` <= insuranceFundBalance.toUint256(). `rawAmount` is the `ETH` (18 digit precision) or collateral token amount (can be less than 18 digit precision) to be withdrawn while `insuranceFundBalance` is a WAD-denominated value (18 digit precision).\\nThe check does not hold if the configured collateral has different precision and may have unwanted consequences, e.g. the withdrawal of more funds than expected.\\nNote: there is another check for `insuranceFundBalance` staying positive after the potential external call to collateral.\\n```\\nfunction withdrawFromInsuranceFund(uint256 rawAmount) public onlyWhitelistAdmin {\\n    require(rawAmount > 0, "invalid amount");\\n    require(insuranceFundBalance > 0, "insufficient funds");\\n    require(rawAmount <= insuranceFundBalance.toUint256(), "insufficient funds");\\n\\n    int256 wadAmount = toWad(rawAmount);\\n    insuranceFundBalance = insuranceFundBalance.sub(wadAmount);\\n    withdrawFromProtocol(msg.sender, rawAmount);\\n\\n    require(insuranceFundBalance >= 0, "negtive insurance fund");\\n\\n    emit UpdateInsuranceFund(insuranceFundBalance);\\n}\\n```\\n\\nWhen looking at the test-cases there seems to be a misconception about what unit of amount `withdrawFromInsuranceFund` is taking. For example, the insurance fund withdrawal and deposit are not tested for collateral that specifies a precision that is not 18. The test-cases falsely assume that the input to `withdrawFromInsuranceFund` is a WAD value, while it is taking the collateral's `rawAmount` which is then converted to a WAD number.\\ncode/test/test_perpetual.js:L471-L473\\n```\\nawait perpetual.withdrawFromInsuranceFund(toWad(10.111));\\nfund = await perpetual.insuranceFundBalance();\\nassert.equal(fund.toString(), 0);\\n```\\n

Impact:

Recommended mitigation:
Check that `require(wadAmount <= insuranceFundBalance.toUint256(), "insufficient funds");`, add a test-suite testing the insurance fund with collaterals with different precision and update existing tests that properly provide the expected input to `withdraFromInsurance`.
Vulnerability: Perpetual - liquidateFrom should not have public visibility  Pending
Severity: high

Description:
`Perpetual.liquidate` is used to liquidate an account that is “unsafe,” determined by the relative sizes of `marginBalanceWithPrice` and maintenanceMarginWithPrice:\\n```\\n// safe for liquidation\\nfunction isSafeWithPrice(address guy, uint256 currentMarkPrice) public returns (bool) {\\n    return\\n        marginBalanceWithPrice(guy, currentMarkPrice) >=\\n        maintenanceMarginWithPrice(guy, currentMarkPrice).toInt256();\\n}\\n```\\n\\n`Perpetual.liquidate` allows the caller to assume the liquidated account's position, as well as a small amount of “penalty collateral.” The steps to liquidate are, roughly:\\nClose the liquidated account's position\\nPerform a trade on the liquidated assets with the liquidator acting as counter-party\\nGrant the liquidator a portion of the liquidated assets as a reward. An additional portion is added to the insurance fund.\\nHandle any losses\\nWe found several issues in Perpetual.liquidate:\\n`liquidateFrom` has `public` visibility:\\n```\\nfunction liquidateFrom(address from, address guy, uint256 maxAmount) public returns (uint256, uint256) {\\n```\\n\\nGiven that `liquidate` only calls `liquidateFrom` after checking the current contract's status, this oversight allows anyone to call `liquidateFrom` during the `SETTLED` stage:\\n```\\nfunction liquidate(address guy, uint256 maxAmount) public returns (uint256, uint256) {\\n    require(status != LibTypes.Status.SETTLED, "wrong perpetual status");\\n    return liquidateFrom(msg.sender, guy, maxAmount);\\n}\\n```\\n\\nAdditionally, directly calling `liquidateFrom` allows anyone to liquidate on behalf of other users, forcing other accounts to assume liquidated positions.\\nFinally, neither `liquidate` nor `liquidateFrom` check that the liquidated account and liquidator are the same. Though the liquidation accounting process is hard to follow, we believe this is unintended and could lead to large errors in internal contract accounting.

Impact:

Recommended mitigation:
Make `liquidateFrom` an `internal` function\\nIn `liquidate` or `liquidateFrom`, check that `msg.sender != guy`
Vulnerability: AMM - Governance is able to set an invalid alpha value  Pending
Severity: medium

Description:
According to https://en.wikipedia.org/wiki/Moving_average\\nThe coefficient α represents the degree of weighting decrease, a constant smoothing factor between 0 and 1. A higher α discounts older observations faster.\\nHowever, the code does not check upper bounds. An admin may, therefore, set an invalid alpha that puts `emaAlpha2` out of bounds or negative.\\n```\\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```\\n

Impact:

Recommended mitigation:
Ensure that the system configuration is always within safe bounds. Document expected system variable types and their safe operating ranges. Enforce that bounds are checked every time a value is set. Enforce safe defaults when deploying contracts.\\nEnsure `emaAlpha` is `0 < value < 1 WAD`