diff --git a/.scripts/solodit/AAVE_protocol_v2_README_fixed.md b/.scripts/solodit/AAVE_protocol_v2_README_fixed.md new file mode 100644 index 0000000..1fd884a --- /dev/null +++ b/.scripts/solodit/AAVE_protocol_v2_README_fixed.md @@ -0,0 +1,276 @@ +## Report + +### CRITICAL + +Not found + +### MAJOR + +#### Missing Leading 'F' in LIQUIDATION_BONUS_MASK in ReserveConfiguration.sol + + +##### Description + +https://github.com/aave/protocol-v2/blob/f435b2fa0ac589852ca3dd6ae2b0fbfbc7079d54/contracts/libraries/configuration/ReserveConfiguration.sol#L18 + +One leading `F` is missing in this mask. + +```solidity +uint256 constant LIQUIDATION_BONUS_MASK = 0xFFFFFFF0000FFFFFFFF; +``` + +This fact results in the corruption of four bits in the reserve factor field during the operations on the liquidation bonus field. `getLiquidationBonus` is also affected. + +##### Recommendation + +We suggest fixing the mask. We also recommend adding tests for each `ReserveConfiguration` field which have other fields set to some values, perform some actions, restore the field to the original value and make sure that the entire mask is intact. + +##### Status +*Fixed at https://github.com/aave/protocol-v2/commit/5ddd98c52993cbe0093e4a32d14d2aec62939f00* + +#### Improper Bit-Length Validation in Reserve Configuration + + +##### Description + +https://github.com/aave/protocol-v2/blob/f435b2fa0ac589852ca3dd6ae2b0fbfbc7079d54/contracts/libraries/configuration/ReserveConfiguration.sol#L46 + +https://github.com/aave/protocol-v2/blob/f435b2fa0ac589852ca3dd6ae2b0fbfbc7079d54/contracts/libraries/configuration/ReserveConfiguration.sol#L63 + +https://github.com/aave/protocol-v2/blob/f435b2fa0ac589852ca3dd6ae2b0fbfbc7079d54/contracts/libraries/configuration/ReserveConfiguration.sol#L84 + +https://github.com/aave/protocol-v2/blob/f435b2fa0ac589852ca3dd6ae2b0fbfbc7079d54/contracts/libraries/configuration/ReserveConfiguration.sol#L106 + +https://github.com/aave/protocol-v2/blob/f435b2fa0ac589852ca3dd6ae2b0fbfbc7079d54/contracts/libraries/configuration/ReserveConfiguration.sol#L128 + +Bit lengths of the provided values are not checked against bit lengths of the corresponding fields in the `data`. + +For example, here + +```solidity +function setLtv(ReserveConfiguration.Map memory self, uint256 ltv) internal pure { + self.data = (self.data & LTV_MASK) | ltv; +``` + +providing a value greater than `65535` as `ltv` will result in a corruption of the liquidation threshold field. + +##### Recommendation +We recommend making sure that passed values fit in the corresponding fields. + +##### Status +*Fixed at https://github.com/aave/protocol-v2/commit/b3cc9d1a62464998e512cf337c35a87ab459a360* + + +#### Erroneous UserBalance Restriction in Withdrawal Validation + +##### Description + +https://github.com/aave/protocol-v2/blob/f435b2fa0ac589852ca3dd6ae2b0fbfbc7079d54/contracts/libraries/logic/ValidationLogic.sol#L68 + +It looks like `userBalance` is erroneously used instead of `amount`. This will result in overly strict restrictions on withdrawals. + +##### Recommendation +We suggest replacing the argument. + +##### Status +*Fixed at https://github.com/aave/protocol-v2/commit/b4f8592775f41e9e52e0068b3c531a08d0b8750c* + + +#### Uninitialized `availableLiquidity` in Loan Size Calculation. +##### Description + +https://github.com/aave/protocol-v2/blob/f435b2fa0ac589852ca3dd6ae2b0fbfbc7079d54/contracts/libraries/logic/ValidationLogic.sol#L200 + +The `vars.availableLiquidity` field is not initialized before usage. + +```solidity +//calculate the max available loan size in stable rate mode as a percentage of the +//available liquidity +uint256 maxLoanSizeStable = vars.availableLiquidity.percentMul(maxStableLoanPercent); +``` +##### Recommendation +Proper initialization should be added. + +##### Status +*Fixed at https://github.com/aave/protocol-v2/commit/3f714b9dc848d28d1753fd8a673038fda4f024ed* + + +#### Decimals Mismatch in Reserve Configuration Update +##### Description +https://github.com/aave/protocol-v2/blob/f435b2fa0ac589852ca3dd6ae2b0fbfbc7079d54/contracts/lendingpool/LendingPoolConfigurator.sol#L533 + +Changing the decimals here will not automatically change the decimals either in the aToken or in the debt tokens. + +```solidity +function setReserveDecimals(address asset, uint256 decimals) external onlyAaveAdmin { + ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset); + + currentConfig.setDecimals(decimals); + + pool.setConfiguration(asset, currentConfig.data); +``` + +Additionally, the oracle must be updated simultaneously to consider the new value of the decimals. Otherwise, significant mispricing and liquidations may occur. +##### Recommendation +We suggest removing this function. Alternatively, the change may be allowed only for inactive reserve and must be propagated to the tokens. + +##### Status +*Fixed at https://github.com/aave/protocol-v2/commit/bfa26634a61347391f5f1251e837c18e2d381c0e* + + +#### Flawed Stable Debt Calculation Due to Timestamp Mismatch +##### Description +https://github.com/aave/protocol-v2/blob/f435b2fa0ac589852ca3dd6ae2b0fbfbc7079d54/contracts/libraries/logic/ReserveLogic.sol#L341-L347 + +Value `vars.previousStableDebt` calculated this way is actually the current stable debt and always equals to `vars.currentStableDebt`. + +```solidity +//calculate the stable debt until the last timestamp update +vars.cumulatedStableInterest = MathUtils.calculateCompoundedInterest( + vars.avgStableRate, + vars.stableSupplyUpdatedTimestamp +); + +vars.previousStableDebt = vars.principalStableDebt.rayMul(vars.cumulatedStableInterest); +``` + +As a result, the stable debt difference is not taken into account. Moreover, the processed stable debt increment is not recorded in any way. +##### Recommendation +One possible solution is to treat `vars.principalStableDebt` as the previous stable debt and update `StableDebtToken`'s `_totalSupply` and `_totalSupplyTimestamp` after the operation. + +##### Status +*Fixed at https://github.com/aave/protocol-v2/commit/276dee4918d1b76b236195e674132fa7d4ba2324* + + +#### Overestimation of Liquidity in Interest Rate Update. +##### Description +https://github.com/aave/protocol-v2/blob/f435b2fa0ac589852ca3dd6ae2b0fbfbc7079d54/contracts/lendingpool/LendingPool.sol#L582 + +```solidity +IERC20(asset).safeTransferFrom(receiverAddress, vars.aTokenAddress, vars.amountPlusPremium); + +reserve.updateState(); +reserve.cumulateToLiquidityIndex(IERC20(vars.aTokenAddress).totalSupply(), vars.premium); +reserve.updateInterestRates(asset, vars.aTokenAddress, vars.premium, 0); +``` + +https://github.com/aave/protocol-v2/blob/f435b2fa0ac589852ca3dd6ae2b0fbfbc7079d54/contracts/lendingpool/LendingPoolCollateralManager.sol#L521 + +```solidity +IERC20(toAsset).safeTransferFrom( + receiverAddress, + address(vars.toReserveAToken), + vars.amountToReceive +); + +if (vars.toReserveAToken.balanceOf(msg.sender) == 0) { + _usersConfig[msg.sender].setUsingAsCollateral(toReserve.id, true); +} + +vars.toReserveAToken.mint(msg.sender, vars.amountToReceive, toReserve.liquidityIndex); +toReserve.updateInterestRates( + toAsset, + address(vars.toReserveAToken), + vars.amountToReceive, + 0 +); +``` + +`updateInterestRates` needs to be called with `liquidityAdded` set to `0` since liquidity was already transferred to the pool's balance. Otherwise, overestimated liquidity would lead to too low debt interest rates. + +##### Recommendation + +It is recommended to call `updateInterestRates` with `liquidityAdded` set to `0`. + +##### Status +*Fixed at https://github.com/aave/protocol-v2/commit/a2e2450bb351844086f749ee24c005df03bc0e4a* + + +#### Interest Rate Miscalculation Due to Stale Debt Values +##### Description + +https://github.com/aave/protocol-v2/blob/f435b2fa0ac589852ca3dd6ae2b0fbfbc7079d54/contracts/lendingpool/LendingPoolCollateralManager.sol#L227-L232 + +```solidity +principalReserve.updateInterestRates( + principal, + principalReserve.aTokenAddress, + vars.actualAmountToLiquidate, + 0 +); + +if (vars.userVariableDebt >= vars.actualAmountToLiquidate) { + IVariableDebtToken(principalReserve.variableDebtTokenAddress).burn( + user, + vars.actualAmountToLiquidate, + principalReserve.variableBorrowIndex + ); +} else { + IVariableDebtToken(principalReserve.variableDebtTokenAddress).burn( + user, + vars.userVariableDebt, + principalReserve.variableBorrowIndex + ); + + IStableDebtToken(principalReserve.stableDebtTokenAddress).burn( + user, + vars.actualAmountToLiquidate.sub(vars.userVariableDebt) + ); +} +``` + +https://github.com/aave/protocol-v2/blob/f435b2fa0ac589852ca3dd6ae2b0fbfbc7079d54/contracts/lendingpool/LendingPoolCollateralManager.sol#L409-L414 + +```solidity +debtReserve.updateInterestRates( + principal, + vars.principalAToken, + vars.actualAmountToLiquidate, + 0 +); +IERC20(principal).safeTransferFrom(receiver, vars.principalAToken, vars.actualAmountToLiquidate); + +if (vars.userVariableDebt >= vars.actualAmountToLiquidate) { + IVariableDebtToken(debtReserve.variableDebtTokenAddress).burn( + user, + vars.actualAmountToLiquidate, + debtReserve.variableBorrowIndex + ); +} else { + IVariableDebtToken(debtReserve.variableDebtTokenAddress).burn( + user, + vars.userVariableDebt, + debtReserve.variableBorrowIndex + ); + IStableDebtToken(debtReserve.stableDebtTokenAddress).burn( + user, + vars.actualAmountToLiquidate.sub(vars.userVariableDebt) + ); +} +``` + +Debt reserve interest rates are updated before debt burning takes place. + +As a result, stale total debt values are used during interest rates calculation. + +##### Recommendation +We suggest switching `updateInterestRates` and the `if` statement. + +##### Status +*Fixed at https://github.com/aave/protocol-v2/commit/c5d7bb5e80e08a7c901cd7bb41b7bb839c2e0f0e* + + +#### Inaccurate `liquidityAdded` Parameter Before Flashloan Transfer +##### Description + +https://github.com/aave/protocol-v2/blob/56d25e81cb0fdfcac785d669d3577b1ef2d9286e/contracts/lendingpool/LendingPool.sol#L511 + +The `liquidityAdded` parameter of the `updateInterestRates` call seems to be incorrect as the flashloan body is yet to be transferred thus it will not be included in the interest rates calculation. + +##### Recommendation + +It is recommended to fix the `liquidityAdded` parameter. + +##### Status +*Fixed at https://github.com/aave/protocol-v2/commit/584a567635ad4817c7ef105304d62f25158eb120* + diff --git a/.scripts/solodit/EMPTY b/.scripts/solodit/EMPTY new file mode 100644 index 0000000..e69de29 diff --git a/.scripts/solodit/README.md b/.scripts/solodit/README.md new file mode 100644 index 0000000..517d904 --- /dev/null +++ b/.scripts/solodit/README.md @@ -0,0 +1,18 @@ +# Convert to Solodit + +## Install +``` +pip3 install docopt +``` + +## Run + +Simply output solidit data: +``` +python3 convert.py +``` + +Additional options can be set via `config.json` or command line: +``` +python3 convert.py -h +``` diff --git a/.scripts/solodit/config.json b/.scripts/solodit/config.json new file mode 100644 index 0000000..a06a85f --- /dev/null +++ b/.scripts/solodit/config.json @@ -0,0 +1,49 @@ +{ + "index": "../../README.md", + "base_path": "../../", + "urgency_map": { + "critical": "HIGH", + "criticals": "HIGH", + "highs": "HIGH", + "high": "HIGH", + "major": "HIGH", + "majors": "HIGH", + "mediums": "MEDIUM", + "medium": "MEDIUM", + "lows": "LOW", + "low": "LOW", + "infos": "LOW", + "info": "LOW", + "comments": "LOW", + "comment": "LOW" + }, + "fix": { + "https://github.com/mixbytes/audits_public/blob/master/AAVE/protocol%20v2/README.md": { + "file": "AAVE_protocol_v2_README_fixed.md" + }, + "https://github.com/mixbytes/audits_public/blob/master/Lido/Aave%20stETH/README.md": { + "file": "EMPTY" + }, + "https://github.com/mixbytes/audits_public/blob/master/AAVE/ParaSwap%20Adapter/README.md": { + "file": "EMPTY" + }, + "https://github.com/mixbytes/audits_public/blob/master/Empower%20the%20DAO/README.md": { + "file": "EMPTY" + }, + "https://github.com/mixbytes/audits_public/blob/master/Akropolis/Token/README.md": { + "file": "EMPTY" + }, + "https://github.com/mixbytes/audits_public/blob/master/LTO%20Network/Token%20Sale/README.md": { + "file": "EMPTY" + }, + "https://github.com/mixbytes/audits_public/blob/master/KickICO/README.md": { + "file": "EMPTY" + }, + "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/Yearn%20Protocol%20V1/README.md": { + "file": "EMPTY" + }, + "https://github.com/mixbytes/audits_public/blob/master/POA%20Network/POA%20PoPA/README.md": { + "file": "EMPTY" + } + } +} \ No newline at end of file diff --git a/.scripts/solodit/convert.py b/.scripts/solodit/convert.py new file mode 100644 index 0000000..8963360 --- /dev/null +++ b/.scripts/solodit/convert.py @@ -0,0 +1,198 @@ +""" +Parse findings in mixbytes public repo + +Usage: + convert [options] + +Options: + -h help + --config=FILE [default: config.json] + --index=FILE root md file with a table of reports + --path=PATH base path with reports + --debug=FILE run in debug mode over a single report + --list list projects only + --list-errors list only projects with parsing errors +""" +from docopt import docopt +import json +import sys +import re +import os +import md + + +def extract_href_from_md_link(text): + link_pattern = r'\[link\]\((https?://\S+)\)' + return re.findall(link_pattern, text)[0] + + +def extract_file_path_from_link(link): + relative_path = link.replace("https://github.com/mixbytes/audits_public/blob/master/", "").replace("%20", " ") + return relative_path + + +def clean_title(text): + text = text.lower() + text = re.sub("[^a-z]", " ", text) + text = re.sub("\s+", " ", text) + text = text.strip() + return text + + +def find(section, title): + if clean_title(section["title"]) == clean_title(title): + return section + + for section in section["subsections"]: + if found := find(section, title): + return found + + +def parse(text, md_link="", pdf_link=None, protocol_name="", report_date=""): + sections = md.parse_md(text) + + for urgency in config["urgency_map"]: + if findings := find(sections, urgency): + findings = findings["subsections"] + for finding in findings: + + if clean_title(finding["title"]) == "not found" and not finding["subsections"]: + continue + + finding_github_link = md_link + md.generate_hash_link(finding["title"]) + debug_info = finding_github_link + + if ( + re.match("^[0-9]+\. ?https://github.com/", finding["title"], flags=re.I) + or + re.match(r"^([0-9]+\. ?)?\[\w+\.sol\\?#?[L0-9-]+\]\(https://github.com/", + finding["title"], flags=re.I) + ): + raise Exception("Report '%s' have bad vulnerability title" % finding_github_link) + + if not finding["subsections"] and finding["content"]: + content = md.to_md({**finding, "level": 0}) + + else: + description = find(finding, "description") + assert description, f"Description section not found in {debug_info}" + + recommendation = find(finding, "recommendation") + assert recommendation, f"Recommendation section not found in {debug_info}" + + content = md.to_md(description) + "\n" + md.to_md(recommendation) + + yield { + "title": re.sub(r'^[0-9]+\.\s+', '', finding["title"]), + "content": content, + "protocol": protocol_name, + "report_date": report_date, + "impact": config["urgency_map"][urgency], + "finders": [], + "github_link": finding_github_link, + "pdf_link": pdf_link, + } + + +def fix(text, md_link): + for md_link_to_fix, rules in config.get("fix", {}).items(): + if md_link == md_link_to_fix: + if "sub" in rules: + for pattern, repl in rules["sub"].items(): + text = re.sub(pattern, repl, text, flags=re.M) + elif "file" in rules: + return open(rules["file"]).read() + return text + + +def run_from_index(path): + table = md.parse_table(open(path).read()) + base_path = config.get("base_path", "") + outputs = [] + + for report in table: + md_link = extract_href_from_md_link(report["MD Report"]) + path = extract_file_path_from_link(md_link) + path = os.path.join(base_path, path) + + if report["PDF Report"] == "N/A": + pdf_link = None + else: + pdf_link = extract_href_from_md_link(report["PDF Report"]) + + assert os.path.exists(path), f"Report '{md_link}' cannot be found in '{path}'" + + text = open(path).read() + text = fix(text, md_link) + outputs.extend(parse( + text, + md_link=md_link, + protocol_name=report["Project"], + report_date=report["Release Date (YYYY-MM-DD)"], + pdf_link=pdf_link, + )) + + print(json.dumps(outputs, indent=4)) + + +def run_single_report(path): + print(json.dumps(list(parse(open(path).read())), indent=4)) + + +def get_config(args): + config = args["--config"] or "config.json" + assert os.path.exists(config), "Config not found" + config = json.load(open(config)) + + if args["--index"]: + config["index"] = args["--index"] + + if args["--path"]: + config["base_path"] = args["--path"] + + return config + + +if __name__ == "__main__": + args = docopt(__doc__) + config = get_config(args) + + if args["--list"]: + table = md.parse_table(open(config["index"]).read()) + base_path = config.get("base_path", "") + outputs = [] + + for report in table: + md_link = extract_href_from_md_link(report["MD Report"]) + print(md_link) + + elif args["--list-errors"]: + table = md.parse_table(open(config["index"]).read()) + base_path = config.get("base_path", "") + outputs = [] + + for report in table: + md_link = extract_href_from_md_link(report["MD Report"]) + try: + path = extract_file_path_from_link(md_link) + path = os.path.join(base_path, path) + + assert os.path.exists(path), f"Report '{md_link}' cannot be found in '{path}'" + + text = open(path).read() + text = fix(text, md_link) + list(parse( + text, + md_link=md_link, + protocol_name=report["Project"], + report_date=report["Release Date (YYYY-MM-DD)"], + pdf_link="", + )) + except: + print(md_link) + + elif args["--debug"]: + run_single_report(args["--debug"]) + + else: + run_from_index(config["index"]) diff --git a/.scripts/solodit/md.py b/.scripts/solodit/md.py new file mode 100644 index 0000000..ce11ed0 --- /dev/null +++ b/.scripts/solodit/md.py @@ -0,0 +1,233 @@ +from collections import deque +import re + + +def parse_md(text): + """ + Parses Markdown text and extracts data. + + >>> md = ''' + ... # TITLE 1 + ... text 1 + ... ##### TAGS + ... tags + ... ## TITLE 2 + ... text 2 + ... ### TITLE 3 + ... text 3 + ... # TITLE 4 + ... text 4 + ... ''' + + >>> import json + >>> print(json.dumps(parse_md(md), indent=4)) + { + "level": 0, + "title": "", + "content": [], + "subsections": [ + { + "level": 1, + "title": "TITLE 1", + "content": [ + "text 1" + ], + "subsections": [ + { + "level": 5, + "title": "TAGS", + "content": [ + "tags" + ], + "subsections": [] + }, + { + "level": 2, + "title": "TITLE 2", + "content": [ + "text 2" + ], + "subsections": [ + { + "level": 3, + "title": "TITLE 3", + "content": [ + "text 3" + ], + "subsections": [] + } + ] + } + ] + }, + { + "level": 1, + "title": "TITLE 4", + "content": [ + "text 4" + ], + "subsections": [] + } + ] + } + """ + lines = text.strip().split("\n") + sections = deque([{ + "level": 0, + "title": "", + "content": [], + "subsections": [], + }]) + + skip_until = None + CODE = '```' + + def append(line): + sections[-1]["content"].append(line) + + for line in lines: + if line.startswith(CODE): + append(line) + if skip_until == CODE: + skip_until = None + else: + skip_until = CODE + + elif skip_until is not None: + append(line) + + elif line.strip().startswith("#"): + line = line.strip() + level = 0 + for c in line: + if c == "#": + level += 1 + else: + break + sections.append({ + "level": level, + "title": line[level:].strip(), + "content": [], + "subsections": [], + }) + + else: + append(line) + + assert skip_until is None + + def build_subsections(start): + while sections: + next = sections.popleft() + if start["level"] < next["level"]: + start["subsections"].append(build_subsections(next)) + else: + sections.appendleft(next) + break + + return start + + return build_subsections(sections.popleft()) + + +def to_md(parsed_md): + """ + Converts parsed md back to text + + >>> md = ''' + ... # TITLE 1 + ... text 1 + ... ##### TAGS + ... tags + ... ## TITLE 2 + ... text 2 + ... ### TITLE 3 + ... text 3 + ... # TITLE 4 + ... text 4 + ... ''' + + >>> print(to_md(parse_md(md))) + + # TITLE 1 + text 1 + ##### TAGS + tags + ## TITLE 2 + text 2 + ### TITLE 3 + text 3 + # TITLE 4 + text 4 + """ + if not parsed_md: + return "" + + md_text = "" + if parsed_md["level"] > 0: + md_text += "#" * parsed_md["level"] + " " + parsed_md["title"] + "\n" + + md_text += "\n".join(parsed_md["content"]) + + for subsection in parsed_md["subsections"]: + md_text += "\n" + to_md(subsection) + + return md_text + + +def parse_table(text): + """ + >>> example = ''' + ... | Project | Audit Name | MD Report | PDF Report | Release Date (YYYY-MM-DD) | + ... |---|---|---|---|---| + ... | Algebra Finance | Plugins | [link](https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Plugins/README.md) | [link](https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Plugins/Algebra%20Plugins%20Security%20Audit%20Report.pdf) | 2023-09-06 | + ... ''' + >>> parse_table(example) + [{'Project': 'Algebra Finance', 'Audit Name': 'Plugins', 'MD Report': '[link](https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Plugins/README.md)', 'PDF Report': '[link](https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Plugins/Algebra%20Plugins%20Security%20Audit%20Report.pdf)', 'Release Date (YYYY-MM-DD)': '2023-09-06'}] + >>> + """ + lines = text.split("\n") + + # Find the start and end of the table based on horizontal rule lines + table_start = None + table_end = None + for index, line in enumerate(lines): + if "|---" in line: + table_start = index + if table_start and line.strip() == "": + table_end = index + break + + # Extract the table header and rows + header_line = lines[table_start - 1].strip().split("|")[1:-1] + table_rows = [row.strip().split("|")[1:-1] for row in lines[table_start + 1:table_end]] + + # Convert the table to a list of dictionaries + table_data = [] + for row in table_rows: + entry = {header.strip(): value.strip() for header, value in zip(header_line, row)} + table_data.append(entry) + + return table_data + + +def generate_hash_link(title): + """ + >>> generate_hash_link("1. EIP712 DOMAIN_SEPARATOR stored as immutable") + '#1-eip712-domain_separator-stored-as-immutable' + >>> generate_hash_link("2. AMM.exchange() produces negative fees") + '#2-ammexchange-produces-negative-fees' + >>> generate_hash_link("3. Early liquidations via repay() front-running") + '#3-early-liquidations-via-repay-front-running' + >>> generate_hash_link("1. No checks of the result of AMM.withdraw") + '#1-no-checks-of-the-result-of-ammwithdraw' + >>> generate_hash_link("6. ControllerFactory.set_admin() does not have two-step ownership transferring") + '#6-controllerfactoryset_admin-does-not-have-two-step-ownership-transferring' + """ + # Remove special characters and spaces, convert to lowercase + cleaned_title = re.sub(r'[^a-zA-Z0-9_ -]', '', title).strip().lower() + # Replace spaces with hyphens + hash_link = re.sub(r'\s+', '-', cleaned_title) + # Add a hash symbol at the beginning + hash_link = '#' + hash_link + return hash_link diff --git a/.scripts/solodit/output.json b/.scripts/solodit/output.json new file mode 100644 index 0000000..9f332c4 --- /dev/null +++ b/.scripts/solodit/output.json @@ -0,0 +1,5232 @@ +[ + { + "title": "Farming can be deactivated by accident", + "content": "##### Description\nThe current check for farming deactivation can be triggered by accident if `tick` hasn't changed during the swap and `zeroToOne` is false https://github.com/cryptoalgebra/Algebra/blob/6f57b3e218630106a4d41aedefd38f9e83b41e2b/src/farming/contracts/farmings/EternalVirtualPool.sol#L131-L134. This action will disconnect farming from the pool and will affect incentive distribution for users.\n\n##### Recommendation\nWe recommend using this check https://github.com/cryptoalgebra/Algebra/blob/6f57b3e218630106a4d41aedefd38f9e83b41e2b/src/farming/contracts/farmings/EternalVirtualPool.sol#L137-L141 before setting the `deactive` state to the virtual pool.\n", + "protocol": "Algebra Finance", + "report_date": "2023-09-25", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Plugins/README.md#1-farming-can-be-deactivated-by-accident", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Plugins/Algebra%20Plugins%20Security%20Audit%20Report.pdf" + }, + { + "title": "Overflow will entirely block the plugin", + "content": "##### Description\nOverflow will occur here on the second time of the list initialization https://github.com/cryptoalgebra/Algebra/blob/6f57b3e218630106a4d41aedefd38f9e83b41e2b/src/plugins/contracts/libraries/VolatilityOracle.sol#L72-L74. This will block plugin updates that will affect the pool and further recovery can be executed by admin only.\n\n##### Recommendation\nWe recommend using the `unchecked` block here since overflow is desired.\n", + "protocol": "Algebra Finance", + "report_date": "2023-09-25", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Plugins/README.md#2-overflow-will-entirely-block-the-plugin", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Plugins/Algebra%20Plugins%20Security%20Audit%20Report.pdf" + }, + { + "title": "Manipulation of volatility through zero-amount swaps", + "content": "##### Description\nSwaps executed with a zero amount are currently factored into the volatility oracle. This vulnerability allows an attacker to artificially manipulate the volatility index, which in turn affects the dynamic fee calculations to their advantage.\n\nThe issue has been categorized with a MEDIUM severity level. This is because the attacker can manipulate the fee only under specific conditions and within a predefined range.\n##### Recommendation\nTo mitigate this issue, it is recommended to exclude zero-amount swaps from volatility calculations.", + "protocol": "Algebra Finance", + "report_date": "2023-09-25", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Plugins/README.md#1-manipulation-of-volatility-through-zero-amount-swaps", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Plugins/Algebra%20Plugins%20Security%20Audit%20Report.pdf" + }, + { + "title": "Missing flags validation in new `pluginConfig`", + "content": "##### Description\nThere is no validation of flags in new `pluginConfig` set with `AlgebraPool.setPluginConfig()`. This can lead to the invocation of hooks that will constantly revert. E.g. `BEFORE_FLASH_FLAG`, `AFTER_FLASH_FLAG`, `AFTER_SWAP_FLAG` (without currently connected incentive) can be switched on.\nThis issue has a MEDIUM severity since it can partially or fully stop the pool until `pluginConfig` is corrected.\n\n##### Recommendation\nWe recommend moving all interaction with `pluginConfig` to the plugin contract. Any modification of `pluginConfig` should consider the current version and state of the plugin.\n", + "protocol": "Algebra Finance", + "report_date": "2023-09-25", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Plugins/README.md#2-missing-flags-validation-in-new-pluginconfig", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Plugins/Algebra%20Plugins%20Security%20Audit%20Report.pdf" + }, + { + "title": "Plugin timestamps data can be overwritten by a call to the `prepayTimepointsStorageSlot` function", + "content": "##### Description\nThere is an issue at the line https://github.com/cryptoalgebra/Algebra/blob/6f57b3e218630106a4d41aedefd38f9e83b41e2b/src/plugins/contracts/AlgebraBasePluginV1.sol#L67.\nPlugin timestamps data can be overwritten by a call to the `prepayTimepointsStorageSlots` function in cases when the\nplugin was configured from AlgebraPool by a call to `setPluginConfig` (and `setPlugin`) and the `initialize` function inside plugin wasn't called. An attacker can wait for some swaps and data in the timepoints array to overwrite the existing timestamps. But due to uninitialized ticks in the first timepoint, users won't be able to perform many swaps from AlgebraPool because the plugin will operate with null initial data.\nThis issue has been assigned a MEDIUM severity level because an attacker is able to overwrite data only for a few timepoints.\n\n##### Recommendation\nWe recommend restricting the `prepayTimepointsStorageSlots` function to be called only by the plugin factory manager.\n", + "protocol": "Algebra Finance", + "report_date": "2023-09-25", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Plugins/README.md#3-plugin-timestamps-data-can-be-overwritten-by-a-call-to-the-prepaytimepointsstorageslot-function", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Plugins/Algebra%20Plugins%20Security%20Audit%20Report.pdf" + }, + { + "title": "An incorrect comment", + "content": "##### Description\nThere is a comment that says that volume is used to calculate volatility, which is wrong https://github.com/cryptoalgebra/Algebra/blob/6f57b3e218630106a4d41aedefd38f9e83b41e2b/src/plugins/contracts/libraries/AdaptiveFee.sol#L36.\n\n##### Recommendation\nWe recommend updating the comment.\n", + "protocol": "Algebra Finance", + "report_date": "2023-09-25", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Plugins/README.md#1-an-incorrect-comment", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Plugins/Algebra%20Plugins%20Security%20Audit%20Report.pdf" + }, + { + "title": "Farming deactivation can be triggered on the farming entering", + "content": "##### Description\nFarming deactivation can be triggered on the farming entering, so the user who enters farming and deactivates it will need to exit farming immediately to avoid losing rewards.\n\n##### Recommendation\nWe recommend updating the project architecture to account for this scenario.\n", + "protocol": "Algebra Finance", + "report_date": "2023-09-25", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Plugins/README.md#2-farming-deactivation-can-be-triggered-on-the-farming-entering", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Plugins/Algebra%20Plugins%20Security%20Audit%20Report.pdf" + }, + { + "title": "There is no check in `AlgebraEternalFarming._isIncentiveActive()` that the plugin is still connected to the pool", + "content": "##### Description\nhttps://github.com/cryptoalgebra/Algebra/blob/6f57b3e218630106a4d41aedefd38f9e83b41e2b/src/farming/contracts/farmings/AlgebraEternalFarming.sol#L349\nA plugin with some incentive connected to that plugin can be replaced with another plugin by calling `Algebra.setPlugin()`. `AlgebraEternalFarming._isIncentiveActive()` will still return `true` for that incentive for some time even if there is already another active incentive in the new plugin. So, new users can still enter that old incentive and new rewards can be brought to it.\n\n##### Recommendation\nWe recommend adding a check to `AlgebraEternalFarming._isIncentiveActive()` that `Incentive.pluginAddress` is a current pool's plugin.\n", + "protocol": "Algebra Finance", + "report_date": "2023-09-25", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Plugins/README.md#3-there-is-no-check-in-algebraeternalfarming_isincentiveactive-that-the-plugin-is-still-connected-to-the-pool", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Plugins/Algebra%20Plugins%20Security%20Audit%20Report.pdf" + }, + { + "title": "`AlgebraBasePluginV1.isIncentiveActive()` returns true for deactivated incentives", + "content": "##### Description\nThe external view function `AlgebraBasePluginV1.isIncentiveActive()` doesn't check whether the current state of incentive and `EternalVirtualPool` is active or not. It just checks that some incentive is connected to the plugin. So, the result can be misinterpreted.\n\n##### Recommendation\nWe recommend renaming this function.\n", + "protocol": "Algebra Finance", + "report_date": "2023-09-25", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Plugins/README.md#4-algebrabasepluginv1isincentiveactive-returns-true-for-deactivated-incentives", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Plugins/Algebra%20Plugins%20Security%20Audit%20Report.pdf" + }, + { + "title": "TODO comments should be resolved", + "content": "##### Description\nThere are multiple TODO comments - https://github.com/cryptoalgebra/Algebra/blob/6f57b3e218630106a4d41aedefd38f9e83b41e2b/src/farming/contracts/farmings/AlgebraEternalFarming.sol#L169, https://github.com/cryptoalgebra/Algebra/blob/6f57b3e218630106a4d41aedefd38f9e83b41e2b/src/farming/contracts/farmings/AlgebraEternalFarming.sol#L354, https://github.com/cryptoalgebra/Algebra/blob/6f57b3e218630106a4d41aedefd38f9e83b41e2b/src/farming/contracts/FarmingCenter.sol#L87 and https://github.com/cryptoalgebra/Algebra/blob/6f57b3e218630106a4d41aedefd38f9e83b41e2b/src/farming/contracts/FarmingCenter.sol#L115.\n\n##### Recommendation\nWe recommend removing the above-mentioned comments.\n", + "protocol": "Algebra Finance", + "report_date": "2023-09-25", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Plugins/README.md#5-todo-comments-should-be-resolved", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Plugins/Algebra%20Plugins%20Security%20Audit%20Report.pdf" + }, + { + "title": "The risk of storage overflow in volatility oracle", + "content": "##### Description\nThe volatility oracle's storage is constrained by a `UINT16_MODULO` capacity, allowing for approximately 45 values to be recorded per minute over a 24-hour period.\n\nhttps://github.com/cryptoalgebra/Algebra/blob/6f57b3e218630106a4d41aedefd38f9e83b41e2b/src/plugins/contracts/libraries/VolatilityOracle.sol#L14-L15\n\nWhile this capacity is sufficient for the Ethereum mainnet, which generates about 5 blocks per minute, it may be insufficient for other EVM-compatible networks with more frequent block generation. An attacker could exploit this limitation to cause the loss of some volatility data by triggering an excessive number of volatility records.\n\nThis issue has been rated as LOW severity due to its limited impact and the complexity involved in reproducing the exploit.\n##### Recommendation\nTo address this issue, it is recommended to adjust the frequency of volatility storage updates in accordance with both the storage capacity and the desired time window for data retention.\n", + "protocol": "Algebra Finance", + "report_date": "2023-09-25", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Plugins/README.md#6-the-risk-of-storage-overflow-in-volatility-oracle", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Plugins/Algebra%20Plugins%20Security%20Audit%20Report.pdf" + }, + { + "title": "Bypassing payment fees through various methods", + "content": "##### Description\n\nSwapExecutor, a contract responsible for executing token swaps, is vulnerable to multiple methods of bypassing payment fees, allowing an attacker to perform swaps without paying the required fees.\n\nThe first method involves specifying a personal transfer of all tokens in the final swap, leaving only 2 wei of `tokenToTransfer` on the contract to avoid paying fees. This enables the attacker to evade payment and execute swaps at no cost.\n\n- https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/SwapExecutor.sol#L146\n\nThe second method involves passing a swap-path that ends with a poisonous token created by the attacker. The attacker pays fees in their own token, which is worthless, thus bypassing payment fees.\n\n- https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/SwapFacade.sol#L35\n\nThe third method involves copying the code of SwapExecutor and removing the payment logic, allowing the attacker to continue using the SwapFacade without paying any fees by passing the custom SwapExecutor to `SwapFacade.swap()`.\n\n- https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/SwapFacade.sol#L29\n\nOverall, these vulnerabilities allow attackers to perform swaps without paying the required fees, leading to potential financial losses for the SwapExecutor owners.\n\n##### Recommendation\n\nOne way to address the vulnerabilities in SwapExecutor is to take a fixed fee in a fixed token, such as Ether, in SwapFacade.\n", + "protocol": "Barter DAO", + "report_date": "2023-09-05", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/README.md#1-bypassing-payment-fees-through-various-methods", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/Barter%20DAO%20Security%20Audit%20Report%20(diff).pdf" + }, + { + "title": "Hashflow RFQ-integration", + "content": "##### Description\n\nSince we receive `HashflowQuote` before the call occurred, the information at the time of the transaction may not be up to date. \n\nIn that case, due to this code:\n\n```\nif (amount > quote.maxBaseTokenAmount) {\n emit AmountExceedsQuote(amount, quote.maxBaseTokenAmount);\n quote.effectiveBaseTokenAmount = quote.maxBaseTokenAmount;\n} else {\n quote.effectiveBaseTokenAmount = amount;\n}\n```\n\npart of the money may remain with the `SwapExecutor`.\n\n- https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/helpers/HashflowHelper.sol#L24\n\n##### Recommendation\n\nWe recommend adding a revert if the input `amount` is not actual.\n", + "protocol": "Barter DAO", + "report_date": "2023-09-05", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/README.md#2-hashflow-rfq-integration", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/Barter%20DAO%20Security%20Audit%20Report%20(diff).pdf" + }, + { + "title": "Swaps through an ERC777 token can lead to DoS of these swaps", + "content": "##### Description\n\nERC777 tokens allow hooks before and after balance changes.\nTransfer `_from` and `to` can choose the exact receivers of these hooks via `Registry.setInterfaceImplementer()`:\n- [ERC1820Registry](https://etherscan.io/address/0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24)\n\nAlso, Executor allows anyone to call `executeSwap()` and decide on the following targets and calldata.\n\n1) An attacker uses `executeSwap()` so that Executor calls `ERC1820Registry.setInterfaceImplementer(implementer=attacker)`. \n2) User A swaps an ERC777 token to something with low `minReturn`. It must be at least one ERC777 among the list of tokens in swaps.\n3) Executor receives ERC777 tokens from Facade (hook).\n4) The attacker reverts on the hook.\n\nAs a result, any ERC777 token going through Executor will lead to DoS and swap will revert.\n\nSo, one of the attack flows can be like this:\n1) Attacker uses `executeSwap()` so that Executor calls `ERC1820Registry.setInterfaceImplementer(implementer=attacker)'. \nSo, anytime Executor receives ERC777 tokens, a frontrunner contract will be called.\n2) User A swaps the ERC777 tokens to something with low `minReturn`.\n3) Executor receives the ERC777 tokens from Facade (hook).\n4) Attacker contract enters Executor.executeSwap() and Executor thinks that current ERC777 tokens belong to Attacker. So, he can withdraw these tokens, or swap them to something.\n\nOr at least Attacker can revert when recieving a call, not allowing a swap with this token at all.\n\n##### Recommendation\n\nWe recommend that Facade be the only allowed caller for `SwapExecutor.execureSwap()` with the Reentrancy guard and be sure that `minReturn` is set even for small swaps.\n", + "protocol": "Barter DAO", + "report_date": "2023-09-05", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/README.md#3-swaps-through-an-erc777-token-can-lead-to-dos-of-these-swaps", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/Barter%20DAO%20Security%20Audit%20Report%20(diff).pdf" + }, + { + "title": "Facade allows any unauthorized Executor", + "content": "##### Description\n\nSwapFacade allows to choose any SwapExecutor address, even not authored by the team. Fees are charged on SwapExecutor. So, it is rational to fork SwapExecutor with zero fees and choose it as an executor for swaps.\n\n- https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/SwapFacade.sol#L87\n\nSome other possible scenarios:\n- users can choose out date executors\n- users can choose executors with bugs\n\n##### Recommendation\nWe recommend having a list of allowed executors and taking fees on SwapFacade.\n", + "protocol": "Barter DAO", + "report_date": "2023-09-05", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/README.md#1-facade-allows-any-unauthorized-executor", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/Barter%20DAO%20Security%20Audit%20Report%20(diff).pdf" + }, + { + "title": "Anyone can withdraw funds left on `SwapExecutor`", + "content": "##### Description\n\nFunds left on the `SwapExecutor` can be withdrawn by anyone who specifies a transfer call in the swaps.\n\nThere are multiple reasons why funds may be left on the `SwapExecutor`:\n1. A user may not set the `tokenRatio` to 100% in a swap.\n\n```\nuint256 poolSwapAmount = (balanceToSwap * swap.tokenRatio) / _ONE;\n\n# sum (tokenRatio) > _ONE - is not risky, revert happens\n# sum (tokenRatio) < _ONE - is risky, as some tokens \n are left not swapped and can be taken by anyone.\n```\n\n2. The `SwapExecutor` may run arbitrary calls to protocols that reward it with additional tokens. The `SwapFacade` only checks the `tokenToTransfer`, and a user may forget to transfer other tokens from the `SwapExecutor` immediately.\n3. If a user transfers tokens to the `SwapExecutor` first and then runs the `SwapFacade.swap()` function in a separate transaction.\n\n- https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/SwapExecutor.sol#L58\n\n##### Recommendation\nTo address this, a similar approach to that used in CowProtocol could be implemented: allowing only whitelisted managers to execute swaps in SwapExecutor.\n\nIt is also recommended to check that all `tokenRatio` used eventually sum up to 100%. \n", + "protocol": "Barter DAO", + "report_date": "2023-09-05", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/README.md#2-anyone-can-withdraw-funds-left-on-swapexecutor", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/Barter%20DAO%20Security%20Audit%20Report%20(diff).pdf" + }, + { + "title": "ETH value above limited value can be lost", + "content": "##### Description\n\nSwapExecutor has the following lines for ETH:\n\n```\nif (value > valueLimit) {\n value = valueLimit;\n}\n(success, result) = target.call{ value: value }(data);\n```\n\n- https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/SwapExecutor.sol#L116-L120\n\nSo, only a limited amount will be used if sent ETH is above valueLimit.\nThis ETH will be lost on the contract and anyone can withdraw these exceeded amounts.\n\n##### Recommendation\nWe recommend redesigning valueLimit purpose so that no funds are lost in edge situations.\n", + "protocol": "Barter DAO", + "report_date": "2023-09-05", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/README.md#3-eth-value-above-limited-value-can-be-lost", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/Barter%20DAO%20Security%20Audit%20Report%20(diff).pdf" + }, + { + "title": "A swap with permit can be blocked if a frontrunner swaps using copied permit", + "content": "##### Description\n\nFacade does not check that msg.sender is the owner of a permit.\nSo, a frontrunner can use permits of other users available from mempool, so that their transactions would revert (as permit are used by the frontrunner).\n\n- https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/SwapFacade.sol#L58-L64\n\nA user will receive revert and will have to build new calldata, without permit.\n\n##### Recommendation\n\nWe recommend decoding permits to extract their owner, then check that msg.sender is this owner. Some example used by 1inch:\n- https://github.com/1inch/solidity-utils/blob/60fa6eba06f50f2acac5286dea5fb54f206e2434/contracts/libraries/SafeERC20.sol#L158-L245\n\n***", + "protocol": "Barter DAO", + "report_date": "2023-09-05", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/README.md#4-a-swap-with-permit-can-be-blocked-if-a-frontrunner-swaps-using-copied-permit", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/Barter%20DAO%20Security%20Audit%20Report%20(diff).pdf" + }, + { + "title": "Unprotected access to `makeCheckpoint()` in SwapGuardV2", + "content": "##### Description\n\nSwapGuardV2 functions are planned to be used as separate calls in a set of swaps. However, if during the swaps process a hacker manages to get a callback to their own contract (for example, if the victim operates with ERC-777 tokens), the hacker can call public accessible function `makeCheckpoint()` to modify the SwapGuardV2 state so that the `ensureCheckpoint()` function at the victim's end would not work correctly.\n\nhttps://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/SwapGuardV2.sol#L20\n\n##### Recommendation\n\nIt is recommended to revise the approach to using SwapGuardV2. It may be reasonable to leave only one function in SwapGuardV2, which receives a set of tokens, deltas and a callback. The function records the current token balances in memory instead of a storage, then calls the user's callback (which performs swaps), and then checks for changes in the balances.\n", + "protocol": "Barter DAO", + "report_date": "2023-09-05", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/README.md#5-unprotected-access-to-makecheckpoint-in-swapguardv2", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/Barter%20DAO%20Security%20Audit%20Report%20(diff).pdf" + }, + { + "title": "`Ownable` can be upgraded to `Ownable2Step`", + "content": "##### Description\n\nSwapExecutor uses the `Ownable` functionality:\n\nhttps://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/SwapExecutor.sol#L24\n\nThe `Ownable` contract can be upgraded to Open Zeppelin's `Ownable2Step`:\nhttps://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable2Step.sol\n\n`Ownable2Step` provides added safety due to its securely designed two-step process.\n\n\n##### Recommendation\n\nWe recommend applying `Ownable2Step` instead of `Ownable`.\n\n\n***\n", + "protocol": "Barter DAO", + "report_date": "2023-09-05", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/README.md#1-ownable-can-be-upgraded-to-ownable2step", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/Barter%20DAO%20Security%20Audit%20Report%20(diff).pdf" + }, + { + "title": "Simplifying `setFeeAndFeeRecipient()` logic for gas optimization", + "content": "##### Description\n\nThe current implementation manually packs and unpacks the fee and address from a uint256 value, which increases the likelihood of errors and may cause unnecessary gas usage.\n\n* https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/SwapExecutor.sol#L48\n* https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/SwapExecutor.sol#L137\n\n##### Recommendation\n\nTo simplify the logic and optimize gas usage, it's recommended to store the fee and address separately in the contract's state using two separate variables:\n```soliditiy\nuint160 feeAddress;\nuint96 fee;\n```\n\nBoth variables will fit into a single storage slot. This will also allow more efficient retrieval of the fee-related data.\n\n***\n", + "protocol": "Barter DAO", + "report_date": "2023-09-05", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/README.md#2-simplifying-setfeeandfeerecipient-logic-for-gas-optimization", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/Barter%20DAO%20Security%20Audit%20Report%20(diff).pdf" + }, + { + "title": "Missing zero-checks", + "content": "##### Description\n\nThere are no zero checks for `recipient` and `minReturn`:\n* https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/SwapFacade.sol#L32\n* https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/SwapFacade.sol#L33\n\nSome programs may pass zero values for some arguments by default. A user may not notice this behaviour and lose funds.\n\n##### Recommendation\n\nIt is recommended to add requirements which check that the `recipient` and `minReturn` are not zero.\n\n***\n", + "protocol": "Barter DAO", + "report_date": "2023-09-05", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/README.md#3-missing-zero-checks", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/Barter%20DAO%20Security%20Audit%20Report%20(diff).pdf" + }, + { + "title": "SwapGuardV2 has multiple problems", + "content": "##### Description\n\n1. Contracts that use SwapGuardV2 together with Facade+Executor are out of scope\n2. All functions are public and anyone can makeCheckpoint()\n3. This contract will not work with native ETH.\n4. allowedLoss adds up with tokens having different decimals. Or tokensPrices must at least include decimals\n5. Lengths of tokens, tokenPrices and balanceChanges are not checked to be the same\n6. All checkpoints are written to storage, no need if it is used in one transaction\n\n- https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/SwapGuardV2.sol#L20-L58\n\n##### Recommendation\n\nWe recommend using more efficient ways to check profitability of swaps.\n", + "protocol": "Barter DAO", + "report_date": "2023-09-05", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/README.md#4-swapguardv2-has-multiple-problems", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/Barter%20DAO%20Security%20Audit%20Report%20(diff).pdf" + }, + { + "title": "Protection against accidential ETH sendings does not work", + "content": "##### Description\n\nBoth Facade and Executor inherit ContractOnlyEthRecipient.sol with the following code.\n\n```\n/**\n * @title ContractOnlyEthRecipient\n * @notice Base contract that rejects any direct ethereum deposits. \n This is a failsafe against users who can accidentaly send ether\n */\nabstract contract ContractOnlyEthRecipient {\n receive() external payable {\n // solhint-disable-next-line avoid-tx-origin\n if (msg.sender == tx.origin) {\n revert DirectEthDepositIsForbidden();\n }\n }\n}\n```\n\nIn fact, only Executor needs this inheritance, as it can receive ETH from external exchanges.\nBut Facade should only receive ETH as msg.value at swap().\n\nAlso, in the comments developers stated that it is against accidential ETH sendings.\nBy the way, it still allows to receive accidential ETH from users as contracts (like user wallets). Moreover, any accidential ETH on balances are bad (can be stolen), so it is better to remove options to receive accidential money when it\u2019s possible.\n\n##### Recommendation\n\nWe recommend removing `recieve()` for `SwapFacade` and `SwapGuardV2`.\n\n***\n", + "protocol": "Barter DAO", + "report_date": "2023-09-05", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/README.md#5-protection-against-accidential-eth-sendings-does-not-work", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/Barter%20DAO%20Security%20Audit%20Report%20(diff).pdf" + }, + { + "title": "Not effective depositETH() and withdrawETH()", + "content": "##### Description\n\n`depositETH()` and `withdrawETH()` are inherited and make calls to WETH.\n\nIt is used to swap between native ETH and WETH. But the implementation makes Executor call itself (external call), send ETH itself.\n\nThis step is useless and can be dropped.\n\n```\nfunction depositWeth(uint256 amount) external payable {\n if (amount != msg.value) {\n revert EthValueAmountMismatch();\n }\n weth.deposit{value: amount}();\n}\n\nfunction withdrawWeth(uint256 amount) external {\n weth.withdraw(amount);\n}\n```\n\n##### Recommendation\n\nWe recommend removing these functions and use WETH as target directly.\n\n***\n", + "protocol": "Barter DAO", + "report_date": "2023-09-05", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/README.md#6-not-effective-depositeth-and-withdraweth", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/Barter%20DAO%20Security%20Audit%20Report%20(diff).pdf" + }, + { + "title": "Use `encodeCall`", + "content": "##### Description\n\n`abi.encodeCall` is a safer way to avoid mistakes during compilation. The compiler checks that the types of args are compatible with a call.\n\n- https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/helpers/UniswapV2Helper.sol#L31\n- https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/helpers/HashflowHelper.sol#L30\n- https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/helpers/DssPsmHelper.sol#L31\n- https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/helpers/DodoV1Helper.sol#L22\n\n##### Recommendation\n\nWe recommend changing `encodeWithSelector` to `encodeCall`.\n\n***\n", + "protocol": "Barter DAO", + "report_date": "2023-09-05", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/README.md#7-use-encodecall", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/Barter%20DAO%20Security%20Audit%20Report%20(diff).pdf" + }, + { + "title": "Missing caller verification in `uniswapV3SwapCallback()`", + "content": "##### Description\n\nThe `uniswapV3SwapCallback()` function in the `IUniswapV3SwapCallback` interface, which is part of the Uniswap v3 protocol, is used to handle the results of a swap. However, the function in `UniswapV3Executor` does not include any caller verification, which can lead to potential vulnerabilities.\n\n- https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/features/UniswapV3Executor.sol#L20\n\n##### Recommendation\n\nThe uniswap team recommends checking that the caller of the `uniswapV3SwapCallback()` is a `UniswapV3Pool` deployed by the canonical `UniswapV3Factory`:\n- https://github.com/Uniswap/v3-core/blob/main/contracts/interfaces/callback/IUniswapV3SwapCallback.sol\n\nNote that this increases the amount of gas used.\n\n\n***\n", + "protocol": "Barter DAO", + "report_date": "2023-09-05", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/README.md#8-missing-caller-verification-in-uniswapv3swapcallback", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/Barter%20DAO%20Security%20Audit%20Report%20(diff).pdf" + }, + { + "title": "Funds stuck in `SwapFacade` cannot be withdrawn", + "content": "##### Description\n\nERC-20 token funds cannot be withdrawn from SwapFacade if a user accidentally sends tokens to the SwapFacade contract instead of SwapExecutor.\n\n- https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/SwapFacade.sol#L16\n\n##### Recommendation\n\nIt is recommended to add a `sweep(token) onlyOwner` function with the onlyOwner modifier. This function will allow the owner of the contract to sweep any funds that are stuck in the contract and transfer them to a designated account. This will provide a safety net for users who accidentally send funds to the contract, preventing their funds from being lost or stolen.\n\n***\n", + "protocol": "Barter DAO", + "report_date": "2023-09-05", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/README.md#9-funds-stuck-in-swapfacade-cannot-be-withdrawn", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/Barter%20DAO%20Security%20Audit%20Report%20(diff).pdf" + }, + { + "title": "A potential overflow due to unsafe math", + "content": "##### Description\nIn `SwapExecutor` this line `uint256 poolSwapAmount = (balanceToSwap * swap.tokenRatio) / _ONE` allows making overflow.\n\nExample (https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/SwapExecutor.sol#L73):\n```\nuint256 poolSwapAmount = (balanceToSwap * swap.tokenRatio) / _ONE;\n```\n\n##### Recommendation\n\nWe recommend removing unsafe math from critical functions.\n", + "protocol": "Barter DAO", + "report_date": "2023-09-05", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/README.md#10-a-potential-overflow-due-to-unsafe-math", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/Barter%20DAO%20Security%20Audit%20Report%20(diff).pdf" + }, + { + "title": "Use `UniswapV2Router02` to avoid duplication of code", + "content": "##### Description\n\n`UniswapV2Helper` duplicates the existing code of `UniswapV2Router` from the official Uniswap repo.\n\n- https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/helpers/UniswapV2Helper.sol#L18\n\n##### Recommendation\n\nWe recommend using the existing functionality to avoid potential mistakes.\n", + "protocol": "Barter DAO", + "report_date": "2023-09-05", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/README.md#11-use-uniswapv2router02-to-avoid-duplication-of-code", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/Barter%20DAO%20Security%20Audit%20Report%20(diff).pdf" + }, + { + "title": "`SwapFacade.swap()` gas optimisations", + "content": "##### Description\n\nThe logic in `SwapFacade.swap()` can be simplified to always call the `_permit()`.\n\nThe logic at lines 59-73\nhttps://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/SwapFacade.sol#L63\n```solidity\n uint256 currentBalance = sourceToken.balanceOf(address(executor));\nif (currentBalance < amount)\n{\n if (permit.length > 0) {\n _permit(address(sourceToken), permit);\n }\n uint256 approveAmount = sourceToken.allowance(\n msg.sender,\n address(this)\n );\n if (approveAmount < amount) {\n revert NotEnoughApprovedFundsForSwap(approveAmount, amount);\n }\n sourceToken.safeTransferFrom(msg.sender, address(executor), amount);\n}\n```\n\ncan be simplified down to just two lines (always call `_permit()`):\n\n```solidity\n_permit(address(sourceToken), permit);\nsourceToken.safeTransferFrom(msg.sender, address(executor), amount);\n```\n\nNote that the 1inch `_permit()` is already checking `permit.length` and does nothing in case it is zero:\n```solidity\ncontract Permitable {\n error BadPermitLength();\n\n function _permit(address token, bytes calldata permit) \n internal virtual {\n if (permit.length > 0) {\n bool success;\n if (permit.length == 32 * 7) {\n // solhint-disable-next-line avoid-low-level-calls\n (success,) = token.call(\n abi.encodePacked(IERC20Permit.permit.selector, permit)\n );\n } else if (permit.length == 32 * 8) {\n // solhint-disable-next-line avoid-low-level-calls\n (success,) = token.call(\n abi.encodePacked(IDaiLikePermit.permit.selector, permit)\n );\n } else {\n revert BadPermitLength();\n }\n if (!success) {\n RevertReasonForwarder.reRevert();\n }\n }\n }\n}\n```\n\n##### Recommendation\n\nIt is recommended to remove unnecessary conditions to save gas.\n\n***\n\n", + "protocol": "Barter DAO", + "report_date": "2023-09-05", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/README.md#12-swapfacadeswap-gas-optimisations", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO%20(diff)/Barter%20DAO%20Security%20Audit%20Report%20(diff).pdf" + }, + { + "title": "Incorrect `defaultedDebt` interest accrual", + "content": "##### Description\nhttps://github.com/prisma-fi/prisma-contracts/blob/52b26b8a2f1904b048754d5443e08d2144610b92/contracts/core/TroveManager.sol#L1201\n\nIn Prisma, there are liquidations which distribute the debt and collateral from liquidated troves among the remaining ones. For example, these are liquidations when ICR < 100% or liquidations the size of which the StabilityPool cannot cover. Each liquidation of this kind increases the values of `defaultedDebt`, `L_debt`, and `L_collateral` in the relevant TroveManager. These variables are used to track the total debt for each trove.\n\nThe `_applyPendingRewards()` function is triggered with every user interaction with a trove and increases the `trove.debt` by the pending debt from the `defaultedDebt` pool, but only if `rewardSnapshots[trove].collateral < L_collateral`:\n```\nfunction _applyPendingRewards\n ...\n if (rewardSnapshots[_borrower].collateral < L_collateral) {\n ...\n // add pending interest\n debt = debt + pendingDebtReward;\n ...\n }\n ...\n // update trove debt\n t.debt = debt;\n```\nhttps://github.com/prisma-fi/prisma-contracts/blob/52b26b8a2f1904b048754d5443e08d2144610b92/contracts/core/TroveManager.sol#L1201\n\nOver time, the value of `L_debt` and the size of `defaultedDebt` increase:\n```\nfunction _redistributeDebtAndColl\n ...\n if (lastIndexUpdateCached < block.timestamp) {\n ...\n uint256 accruedInterest = Math.mulDiv(defaultedDebt, interestFactor,\n INTEREST_PRECISION);\n ...\n debtWithInterests += accruedInterest;\n }\n ...\n defaultedDebt += debtWithInterests;\n```\nhttps://github.com/prisma-fi/prisma-contracts/blob/52b26b8a2f1904b048754d5443e08d2144610b92/contracts/core/TroveManager.sol#L1367\n\nHowever, `L_collateral` can remain the same until the next bad liquidation (i.e., a liquidation with ICR < 100% or a liquidation which StabilityPool cannot cover).\n\nThus, if a hacker triggers `_applyPendingRewards()` for themselves after a bad liquidation (which increases `L_collateral` and `L_debt`), for example, using the `claimReward()` function, they will set their `rewardSnapshots[hacker].collateral` equal to the new `L_collateral`, and subsequent increases in the `L_debt` variable over time will be incorrectly tracked for them.\n\nFor example, the `getTroveCollAndDebt()` function will return the correct debt for the hacker, including the accumulated `defaultedDebt` interest. However, `_applyPendingRewards()` will not update the `trove.debt` variable because the condition `rewardSnapshots[hacker].collateral < L_collateral` is not satisfied as `L_collateral` remained unchanged. This allows the hacker to close their trove without paying the accrued `defaultedDebt` interest, which can be arbitrarily large. Upon trove closure, all their pending interest will be distributed among unsuspecting remaining troves.\n\nThis leads to instant losses for all troves, which will be forced to pay off the accumulated debt in `defaultedDebt` on behalf of the hacker, and it also leads to instability in the system when a multitude of troves can suddenly go underwater due to the sudden distribution of unpaid debt by the hacker.\n\nThe PoC was sent to the Prism team.\n\n##### Recommendation\nThe issue with incorrect interest accrual could be addressed by expanding the check in the `_applyPendingRewards()` function as follows:\n```\nif (\n (rewardSnapshots[_borrower].collateral < L_collateral)\n ||\n (rewardSnapshots[_borrower].debt < L_debt)\n)\n```\n\nHowever, it's worth noting that the `defaultedDebt` pool can only be zeroed out if after a bad liquidation, the `_applyPendingRewards()` function is called for absolutely all troves in the system, which transfers the debt from `defaultedDebt` to the `totalActiveDebt` pool:\n```\n_movePendingTroveRewardsToActiveBalance(pendingDebtReward, \npendingCollateralReward);\n```\n\nThis is not practically possible. Therefore, `defaultedDebt` will remain positive because some accounts in the system will be inactive. Consequently, the interest accumulated over time in the `defaultedDebt` pool will be distributed among all other active accounts. This seems unfair to active accounts, who will have to pay for the debts of inactive users.\n\nTherefore, the best solution seems to be a complete abandonment of interest accrual on the `defaultedDebt` pool.\n", + "protocol": "Prisma Finance", + "report_date": "2023-09-01", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/README.md#1-incorrect-defaulteddebt-interest-accrual", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/Prisma%20Finance%20Security%20Audit%20Report.pdf" + }, + { + "title": "Mint awards can be manipulated", + "content": "##### Description\n- https://github.com/prisma-fi/prisma-contracts/blob/52b26b8a2f1904b048754d5443e08d2144610b92/contracts/core/TroveManager.sol#L135\n\nMint awards can be manipulated. Next steps:\n\n1. A hacker waits until TCR becomes 149% in TroveManager\n2. The hacker takes the collateral flashloan and inside the transaction:\n- Open a \"huge\" trove to get \"accountLatestMint\" (mint awards https://github.com/prisma-fi/prisma-contracts/blob/52b26b8a2f1904b048754d5443e08d2144610b92/contracts/core/TroveManager.sol#L1018). No commission due to recovery mode (https://0xsydbs-organization.gitbook.io/prisma-finance/core-protocol-operations/recovery-mode#impact-on-fees).\n- Open a \"small\" trove to increase TCR from 149% to 150% (by hacker_helper).\n- In the end, recovery mode is more than 150, and the hacker can close the \"huge\" trove without a commission.\n3. The hacker has a huge \"accountLatestMint\" after flashloan and they can claim prisma tokens.\n\nThe script has been provided.\n\n##### Recommendation\nThis finding shows a way to open any trove without a commission. It is not recommended to give awards for minting directly (https://github.com/prisma-fi/prisma-contracts/blob/52b26b8a2f1904b048754d5443e08d2144610b92/contracts/core/TroveManager.sol#L1018).\n\nWe recommend revising the architecture of rewards.\n", + "protocol": "Prisma Finance", + "report_date": "2023-09-01", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/README.md#2-mint-awards-can-be-manipulated", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/Prisma%20Finance%20Security%20Audit%20Report.pdf" + }, + { + "title": "An attacker can steal the StabilityPool depositors profit", + "content": "##### Description\nThe liquidation flow of the protocol is supposed to be as follows:\n- users open troves and join `StabilityPool`\n- anyone calls liquidation that iterates the given troves and liquidates them one by one\n- in `StabilityPool` there are more collateral tokens\n\nBy using a flash loan, any user can bypass the provision of liquidity to the protocol for a long time and steal some of the `StabilityPool` provider's profit taking the following steps:\n1. An attacker gets a flash mint (https://github.com/prisma-fi/prisma-contracts/blob/52b26b8a2f1904b048754d5443e08d2144610b92/contracts/core/DebtToken.sol#L199).\n2. The attacker makes a deposit `mkUSD` to `StabilityPool`.\n3. The attacker calls the [`liquidateTroves`](https://github.com/prisma-fi/prisma-contracts/blob/52b26b8a2f1904b048754d5443e08d2144610b92/contracts/core/LiquidationManager.sol#L143) function to liquidate the troves.\n4. The attacker calls [`withdrawFromSP`](https://github.com/prisma-fi/prisma-contracts/blob/52b26b8a2f1904b048754d5443e08d2144610b92/contracts/core/StabilityPool.sol#L241)\n5. The attacker gets profit and returns the flash loan.\n\nThe attack's impact:\n- loss of profit from liquidations by `StabilityPool` providers;\n- decreased motivation to use the Stability Pool which may cause mkUSD to unpeg.\n\n##### Recommendation\nWe recommend that you use the time factor to prevent flash loan attacks.\n", + "protocol": "Prisma Finance", + "report_date": "2023-09-01", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/README.md#1-an-attacker-can-steal-the-stabilitypool-depositors-profit", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/Prisma%20Finance%20Security%20Audit%20Report.pdf" + }, + { + "title": "Whale governance attack on the protocol takes 1 day and cannot be cancelled by DAO", + "content": "##### Description\n\nThe flow of the attack:\n1) A whale prepares funds so that the lock for one week gives a weight to bypass the `passingPct`.\n2) In the end of week [N], one minute before week [N+1], the whale calls`TokenLocker.lock(week=1)`. The token locker will register the weight for week [N]\n3) Week [N+1] begins in one minute after Step 2. The funds for the attack are unlocked and can be withdrawn.\n4) The whale calls `AdminVoting.createNewProposal()`\nThe payload is the following:\n-- `PrismaCore.setGuardian()`\n-- `Treasury.transferTokens(token=prisma, receiver=whale, amount=everything)`\n5) The whale calls \n`AdminVoting.voteForProposal()` and votes for the proposal from Step 4.\nAdminVoting uses weights from the previous week [N] which is already finalized and the whale was the largest voter at the end of the week.\nThe whale bypasses `passingPct` for this proposal, so the proposal can be executed in 1 day.\n6) In one day, the whale calls\n`AdminVoting.executeProposal()` and withdraws all funds from the Treasury.\n\nThe guardian cannot cancel this attack. Because the first call in the payload is `PrismaCore.setGuardian()` which is the only type of call that cannot be cancelled, thus the whole payload cannot be cancelled.\n- https://github.com/prisma-fi/prisma-contracts/blob/c0122d27677cd4e1aaee7f1e21f807ccadf46ac8/contracts/dao/AdminVoting.sol#L193-L196\n\n##### Recommendation\nWe recommend that:\n- the guardian restriction to cancel `PrismaCore.setGuardian()` should be fixed. For example, the guardian is not allowed to cancel `PrismaCore.setGuardian()` only if `payload.length == 1`. In this case proposers must have only one call in the payload. Otherwise, the guardian can cancel.\n- when a proposal changes a guardian the protocol can require higher `passingPct`.\n", + "protocol": "Prisma Finance", + "report_date": "2023-09-01", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/README.md#2-whale-governance-attack-on-the-protocol-takes-1-day-and-cannot-be-cancelled-by-dao", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/Prisma%20Finance%20Security%20Audit%20Report.pdf" + }, + { + "title": "Small amounts can be withdrawn without penalties from TockenLocker", + "content": "##### Description\n- https://github.com/prisma-fi/prisma-contracts/blob/c0122d27677cd4e1aaee7f1e21f807ccadf46ac8/contracts/dao/TokenLocker.sol#L806\n\nThere's a rounding error in the penalty calculation:\n```\nuint256 penaltyOnAmount = (lockAmount * weeksToUnlock) / MAX_LOCK_WEEKS;\n```\n\nThe penalty becomes zero if `lockAmount * weeksToUnlock < MAX_LOCK_WEEKS`. For example, if `lockToTokenRatio=1e18`, then 1e18 PRISM is locked for 51 weeks (or alternatively, 51e18 PRISMA is locked for 1 week) can be withdrawn without penalties.\n\nOne example of an attack that allows you to withdraw 23% of the tokens from the `AllocationVesting` contract:\n- We send a small amount of tokens using `allocation_vesting.transferPoints` to any of the addresses (https://github.com/prisma-fi/pris`ma-contracts/blob/c0122d27677cd4e1aaee7f1e21f807ccadf46ac8/contracts/dao/AllocationVesting.sol#L83)\n- Lock these tokens `allocation_vesting.lockFutureClaims` releasing 23% of future transfers (https://github.com/prisma-fi/prisma-contracts/blob/c0122d27677cd4e1aaee7f1e21f807ccadf46ac8/contracts/dao/AllocationVesting.sol#L116)\n- Call `locker.withdrawWithPenalty` in a loop (https://github.com/prisma-fi/prisma-contracts/blob/c0122d27677cd4e1aaee7f1e21f807ccadf46ac8/contracts/dao/TokenLocker.sol#L769). In this case, the commission is not taken\n- Get PRISMA tokens without blocking for 12 weeks\n\nPoC has been sent to the customer.\n\n##### Recommendation\n\nWe recommended that you improve the precision of the penalty calculation or prohibit the early withdrawal of small amounts.\n", + "protocol": "Prisma Finance", + "report_date": "2023-09-01", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/README.md#3-small-amounts-can-be-withdrawn-without-penalties-from-tockenlocker", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/Prisma%20Finance%20Security%20Audit%20Report.pdf" + }, + { + "title": "The implementation of contracts is mutable in Factory", + "content": "##### Description\n- https://github.com/prisma-fi/prisma-contracts/blob/52b26b8a2f1904b048754d5443e08d2144610b92/contracts/core/Factory.sol#L131\n\n`troveManagerImpl` can be changed (https://github.com/prisma-fi/prisma-contracts/blob/52b26b8a2f1904b048754d5443e08d2144610b92/contracts/core/Factory.sol#L124).\n\nIn `Factory` `cloneDeterministic` (`create2`) `troveManagerImpl` is used as a base contract for copying contracts, so the `getTroveManager` method may return incorrect results if `troveManagerImpl` is changed.\n\n##### Recommendation\nWe recommend revising `predictDeterministicAddress` and getting the trove manager using a collateral.\n", + "protocol": "Prisma Finance", + "report_date": "2023-09-01", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/README.md#1-the-implementation-of-contracts-is-mutable-in-factory", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/Prisma%20Finance%20Security%20Audit%20Report.pdf" + }, + { + "title": "Users can lock tokens for a few seconds and receive the same weight as users with a one week lock", + "content": "##### Description\n\nThe weight received right after the lock is stored in the `accountWeeklyWeights[currentWeek]`.\n- https://github.com/prisma-fi/prisma-contracts/blob/c0122d27677cd4e1aaee7f1e21f807ccadf46ac8/contracts/dao/TokenLocker.sol#L441\n\nImagine two users:\n1) the first one locks tokens at the **first** seconds of week 6, duration is 1 week;\n2) the second one locks tokens at the **last** seconds of week 6, duration is 1 week. \n\nBoth of them will receive the weight of `tokenAmount*1` and both of them will have all their tokens unlocked in week 7. They can withdraw their unlocked tokens in the first seconds of week 7.\n\nIt means that the protocol treats these two users identically though the first user locked PRISMA tokens for 1 week and the second one in fact locked tokens for only a few seconds.\n\n##### Recommendation\n\nWe recommend requiring the minimum length of the lock for more than 1 week. It would allow the protocol to have a liquidity lock for at least 1 week even in case of malicius locks in last seconds.\n", + "protocol": "Prisma Finance", + "report_date": "2023-09-01", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/README.md#2-users-can-lock-tokens-for-a-few-seconds-and-receive-the-same-weight-as-users-with-a-one-week-lock", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/Prisma%20Finance%20Security%20Audit%20Report.pdf" + }, + { + "title": "A guardian cannot cancel a malicious proposal in AdminVoting", + "content": "##### Description\nhttps://github.com/prisma-fi/prisma-contracts/blob/c0122d27677cd4e1aaee7f1e21f807ccadf46ac8/contracts/dao/AdminVoting.sol#L186\n\nA user can create a new proposal via `createNewProposal()` with a payload of actions. A guardian, however, is prohibited from using `cancelProposal()` on a proposal, if the first action is a call to `IPrismaCore.setGuardian()`. Therefore, if the proposal contains a malicious action, the guardian is unable to cancel it.\n\n##### Recommendation\n\nOur recommendation is to allow the cancellation of a proposal if its `payload.length > 1`.\n", + "protocol": "Prisma Finance", + "report_date": "2023-09-01", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/README.md#3-a-guardian-cannot-cancel-a-malicious-proposal-in-adminvoting", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/Prisma%20Finance%20Security%20Audit%20Report.pdf" + }, + { + "title": "No time to cancel a malicious proposal in AdminVoting", + "content": "##### Description\n\n- https://github.com/prisma-fi/prisma-contracts/blob/c0122d27677cd4e1aaee7f1e21f807ccadf46ac8/contracts/dao/AdminVoting.sol#L211\n\nA malicious whale can create a proposal, wait for `MIN_TIME_TO_EXECUTION + 1` (currently 24 hours), and then vote and execute it in the same block, leaving no time for a guardian to cancel it.\n\nIt becomes possible because of `MIN_TIME_TO_EXECUTION < VOTING_PERIOD` and there are only two requirements to execute a proposal:\n```\nrequire(proposal.currentWeight >= proposal.requiredWeight, \"Not passed\");\nrequire(proposal.createdAt + MIN_TIME_TO_EXECUTION < block.timestamp,\n\"MIN_TIME_TO_EXECUTION\");\n```\n\n##### Recommendation\n\nWe recommend adding a delay between the point in time when the proposal gains enough votes for execution and the execution itself.\n", + "protocol": "Prisma Finance", + "report_date": "2023-09-01", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/README.md#4-no-time-to-cancel-a-malicious-proposal-in-adminvoting", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/Prisma%20Finance%20Security%20Audit%20Report.pdf" + }, + { + "title": "`1e18-1` wei PRISMA can get lost in `AllocationVesting.lockFutureClaimsWithReceiver()`", + "content": "##### Description\n\n- https://github.com/prisma-fi/prisma-contracts/blob/d9a2b2ba4d26e01115731fffadd8306c5955a660/contracts/dao/AllocationVesting.sol#L172-L173\n\nIn function `AllocationVesting.lockFutureClaimsWithReceiver()`, an `amount` of tokens is debited from the user. However, a number with a rounding error is locked:\n```\ntokenLocker.lock(receiver, amount / lockToTokenRatio, 52);\n```\n\nIf `lockToTokenRatio==1e18`, then the dust up to 1e18 wei PRISMA will be lost by the user and will accumulate in the `AllocationVesting` contract.\n\n##### Recommendation\n\nIt seems that the loss of `1e18-1` wei PRISMA would be unpleasant for the user, so it's recommended to prevent this.\n\nOne way to do this is to discard the dust at the beginning of the function:\n```\nfunction lockFutureClaimsWithReceiver(\n address account,\n address receiver,\n uint256 amount\n) public callerOrDelegated(account) {\n amount = (amount / lockToTokenRatio) * lockToTokenRatio; \n // truncating the dust\n ...\n```\n\n", + "protocol": "Prisma Finance", + "report_date": "2023-09-01", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/README.md#5-1e18-1-wei-prisma-can-get-lost-in-allocationvestinglockfutureclaimswithreceiver", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/Prisma%20Finance%20Security%20Audit%20Report.pdf" + }, + { + "title": "Using the `RESPONSE_TIMEOUT` constant for all oracles", + "content": "##### Description\n\n- https://github.com/prisma-fi/prisma-contracts/blob/d9a2b2ba4d26e01115731fffadd8306c5955a660/contracts/core/PriceFeed.sol#L58\n\nChainlink uses the heartbeat when checking if the data feed is fresh.\n\nCurrently, the `25 hours` constant is used for the definition of staling. However, there are feeds that update the data faster (for example, https://data.chain.link/ethereum/mainnet/crypto-usd/eth-usd).\n\nWithout this, data can be considered fresh for a long time.\n\n##### Recommendation\n\nIt is recommended not to use the `RESPONSE_TIMEOUT` constant. Each oracle can contain this variable.\n\n", + "protocol": "Prisma Finance", + "report_date": "2023-09-01", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/README.md#6-using-the-response_timeout-constant-for-all-oracles", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/Prisma%20Finance%20Security%20Audit%20Report.pdf" + }, + { + "title": "A flashmint max amount check is easily bypassed", + "content": "##### Description\nUsers can take two or more flashloans and bypass the requirement of the `maxFlashLoan()` size.\n- https://github.com/prisma-fi/prisma-contracts/blob/52b26b8a2f1904b048754d5443e08d2144610b92/contracts/core/DebtToken.sol#L155C14-L157\n\nThe current cap for flashloans is set to `2**128`.\nIf this check aims to limit the flashloan amount in order not to exceed max totalSupply, take into account that OpenZeppelin\u00b4s ERC20 will not allow new totalSupply overflow `2**256` limit.\n- https://github.com/OpenZeppelin/openzeppelin-contracts/blob/f29307cfe08c7d76d96a38bf94bab5fec223c943/contracts/token/ERC20/ERC20.sol#L243\n\n##### Recommendation\nWe recommend either removing this check or introducing a reentrancy protection for the flashloan function only.\n", + "protocol": "Prisma Finance", + "report_date": "2023-09-01", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/README.md#1-a-flashmint-max-amount-check-is-easily-bypassed", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/Prisma%20Finance%20Security%20Audit%20Report.pdf" + }, + { + "title": "The callerOrDelegated specification is not followed for CloseTrove", + "content": "##### Description\nFor all key functions in `BorrowerOperations` users can choose their privileged address to delegate an operation.\n- https://github.com/prisma-fi/prisma-contracts/blob/52b26b8a2f1904b048754d5443e08d2144610b92/contracts/dependencies/DelegatedOps.sol#L22-L29\n\nComment there states that:\n```\nIn executing the call, \nall internal state updates \nshould be applied for `account` \nand all value transfers \nshould occur to or from the caller.\n```\nIt is not the case for `closeTrove()`.\n- https://github.com/prisma-fi/prisma-contracts/blob/52b26b8a2f1904b048754d5443e08d2144610b92/contracts/core/BorrowerOperations.sol#L393-L398\nHere, the contract closes the trove taking debtToken from `msg.sender` (as it should), but the remaining collateral is sent to `account`, so the specification is not followed.\n\n##### Recommendation\nWe recommend either sending collateral to `msg.sender` or fixing the comment describing the desired behavior.\n", + "protocol": "Prisma Finance", + "report_date": "2023-09-01", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/README.md#2-the-callerordelegated-specification-is-not-followed-for-closetrove", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/Prisma%20Finance%20Security%20Audit%20Report.pdf" + }, + { + "title": "During the global pause users can increase and decrease TCR", + "content": "##### Description\nWe have two contracts that check the global pause:\n- BorrowerOperations.sol (BO)\n- StabilityPool.sol (SP)\n\nThese contracts have the following functions for users and sometimes they are allowed to be called during the global pause.\n\nfunction | allowed on pause ?\n--- | ---\nBO.openTrove() | no\nBO.addColl() | no\nBO.withdrawCall() | yes\nBO.withdrawDebt() | no\nBO.repayDebt() | yes\nBO.adjustTrove() | allowed if adjusted to [no more collateral] & [less debt]\nBO.closeTrove() | yes\nSP.provideToSP() | no\nSP.withdrawFromSP() | yes\n\nWithdrawing collateral makes TCR lower.\nRepaying debt makes TCR higher.\nClosing troves makes TCR lower, likely.\n\nAs a result, the \"pause\" does not serve as a true global pause and does not stop all operations.\n\n##### Recommendation\nWe recommend ensuring that this pause behavior is enough and complete. If the project needs a true global pause, we recommend introducing a new type of pause that stops all functions.\n", + "protocol": "Prisma Finance", + "report_date": "2023-09-01", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/README.md#3-during-the-global-pause-users-can-increase-and-decrease-tcr", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/Prisma%20Finance%20Security%20Audit%20Report.pdf" + }, + { + "title": "TroveManager bytecodes are not recommended to be different", + "content": "##### Description\n`Factory` allows selecting any implementation addresses for `TroveManager` and `SortedTroves`.\n- https://github.com/prisma-fi/prisma-contracts/blob/52b26b8a2f1904b048754d5443e08d2144610b92/contracts/core/Factory.sol#L83-L84\n\nThe problem is that TroveManagers are not completely separated and the TCR calculation is made via iterating through each TroveManager. Thus, the issue in one TroveManager can break the whole system. That is why it is risky that potentially not audited implementations are allowed.\n\n##### Recommendation\nWe recommend ensuring that all connected TroveManagers share the same code. It is better to have new features separated from the audited codebase, e.g. in v2 of the protocol.\n", + "protocol": "Prisma Finance", + "report_date": "2023-09-01", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/README.md#4-trovemanager-bytecodes-are-not-recommended-to-be-different", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/Prisma%20Finance%20Security%20Audit%20Report.pdf" + }, + { + "title": "MCR and CCR management", + "content": "##### Description\n`MCR` and `CCR` are constants:\n- https://github.com/prisma-fi/prisma-contracts/blob/52b26b8a2f1904b048754d5443e08d2144610b92/contracts/dependencies/PrismaBase.sol#L13-L17\n\nOver time, the value and volatility of the collateral token may change. It will require to adapt `MCR` and `CCR` to new market behavior. \n\n##### Recommendation\nWe recommend that you add methods for changing `MCR` and `CCR` parameters.\n", + "protocol": "Prisma Finance", + "report_date": "2023-09-01", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/README.md#5-mcr-and-ccr-management", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/Prisma%20Finance%20Security%20Audit%20Report.pdf" + }, + { + "title": "Use `SafeTransfer`", + "content": "##### Description\nWhen transfer tokens, there are checks for returned value:\n- https://github.com/prisma-fi/prisma-contracts/blob/52b26b8a2f1904b048754d5443e08d2144610b92/contracts/core/TroveManager.sol#L850\n- https://github.com/prisma-fi/prisma-contracts/blob/52b26b8a2f1904b048754d5443e08d2144610b92/contracts/core/TroveManager.sol#L1381\n- https://github.com/prisma-fi/prisma-contracts/blob/52b26b8a2f1904b048754d5443e08d2144610b92/contracts/core/StabilityPool.sol#L679\n\nThis is the right way. But when working with specific tokens, we can use `SafeERC20`.\n\n##### Recommendation\nWe recommend using [SafeERC20](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/utils/SafeERC20.sol).\n\n`SafeERC20` helps:\n- check the boolean return values of ERC20 operations and revert the transaction if they fail;\n- at the same time allowing you to support some non-standard ERC20 tokens that don\u2019t have boolean return values.\n", + "protocol": "Prisma Finance", + "report_date": "2023-09-01", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/README.md#6-use-safetransfer", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/Prisma%20Finance%20Security%20Audit%20Report.pdf" + }, + { + "title": "A note about exotic tokens", + "content": "##### Description\nThe project's current implementation does not account for the unique behaviors associated with rebaseable tokens, fee-on-transfer tokens, ERC-777 (callback) tokens, or non-18 decimal tokens, exposing the system to potential risks and undesirable consequences, if such a token is used as a collateral.\n\n##### Recommendation\nIt is necessary to manage the collateral registration process to ensure that such exotic tokens are not added as part of the protocol.\n", + "protocol": "Prisma Finance", + "report_date": "2023-09-01", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/README.md#7-a-note-about-exotic-tokens", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/Prisma%20Finance%20Security%20Audit%20Report.pdf" + }, + { + "title": "Unused approval from Treasury to TokenLock", + "content": "##### Description\n\nIn the constructor of Treasury we have this line:\n```\n_token.approve(address(_locker), type(uint256).max);\n```\n- https://github.com/prisma-fi/prisma-contracts/blob/c0122d27677cd4e1aaee7f1e21f807ccadf46ac8/contracts/dao/Treasury.sol#L111\n\nBut TokenLocker never takes PrismaTokens from the Treasury. Moreover, TokenLocker does not store Treasury address.\n\n##### Recommendation\n\nThis approval can be removed.\n", + "protocol": "Prisma Finance", + "report_date": "2023-09-01", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/README.md#8-unused-approval-from-treasury-to-tokenlock", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/Prisma%20Finance%20Security%20Audit%20Report.pdf" + }, + { + "title": "`CurveProxy` contract needs to be approved by Curve DAO", + "content": "##### Description\n\nThere is the following line in the methods for blocking CRV tokens (in Curve vesting contract):\n```\nself.assert_not_contract(msg.sender)\n```\n\n- https://github.com/prisma-fi/prisma-contracts/blob/c0122d27677cd4e1aaee7f1e21f807ccadf46ac8/contracts/staking/Curve/CurveProxy.sol#L307\n\nIn order to make`CurveProxy` work, you need to get an approval from the Curve DAO.\n\n##### Recommendation\n\nWe recommend documenting the CurveProxy deployment process.\n", + "protocol": "Prisma Finance", + "report_date": "2023-09-01", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/README.md#9-curveproxy-contract-needs-to-be-approved-by-curve-dao", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/Prisma%20Finance%20Security%20Audit%20Report.pdf" + }, + { + "title": "Events missing", + "content": "##### Description\nThe function should emit an event for better UX in possible integrations:\n- https://github.com/prisma-fi/prisma-contracts/blob/c0122d27677cd4e1aaee7f1e21f807ccadf46ac8/contracts/dao/Treasury.sol#L173.\n\n##### Recommendation\nWe recommend emitting events.\n", + "protocol": "Prisma Finance", + "report_date": "2023-09-01", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/README.md#10-events-missing", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/Prisma%20Finance%20Security%20Audit%20Report.pdf" + }, + { + "title": "Old votes can be called", + "content": "##### Description\n- https://github.com/prisma-fi/prisma-contracts/blob/c0122d27677cd4e1aaee7f1e21f807ccadf46ac8/contracts/dao/AdminVoting.sol#L207\n\n\nOld approved proposals may be called after a long time.\n\nOne example of using this loophole:\n1. A hacker generates a duplicate proposal from the PRISMA team and motivates users to vote for it. \n2. The proposal gets enough votes but doesn't execute `executeProposal`.\n3. After a long time, the hacker returns to this proposal and calls it for their own purposes. \n\n##### Recommendation\n\nWe recommend making the maximum lifetime for the proposal.\n", + "protocol": "Prisma Finance", + "report_date": "2023-09-01", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/README.md#11-old-votes-can-be-called", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/Prisma%20Finance%20Security%20Audit%20Report.pdf" + }, + { + "title": "`AllocationVesting.setAllocations()` allows setting a zero `numberOfWeeks`", + "content": "##### Description\n\n- https://github.com/prisma-fi/prisma-contracts/blob/d9a2b2ba4d26e01115731fffadd8306c5955a660/contracts/dao/AllocationVesting.sol#L94\n\n`setAllocations()` allows an admin to create an allocation with zero `numberOfWeeks`, leading to unexpected behavior. For example, the `_vestedAt()` function for allocations with zero `numberOfWeeks` always returns zero and thus the `claim()` function reverts, so a user can't withdraw funds from such an allocation.\n\nHowever, `transferPoints()` assumes that if an allocation has zero `numberOfWeeks`, then this allocation is empty and therefore rewrites `numberOfWeeks` with the sender's value:\n```\nif (numberOfWeeksTo == 0) {\n allocations[to].numberOfWeeks = numberOfWeeksFrom;\n}\n```\n\n- https://github.com/prisma-fi/prisma-contracts/blob/d9a2b2ba4d26e01115731fffadd8306c5955a660/contracts/dao/AllocationVesting.sol#L130-L133\n\nThus, after transferring additional points, this allocation becomes available for withdrawal.\n\n##### Recommendation\n\nWe recommend adding a check in the `AllocationVesting.setAllocations()` function to ensure that `numberOfWeeks` cannot be zero.\n\n", + "protocol": "Prisma Finance", + "report_date": "2023-09-01", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/README.md#12-allocationvestingsetallocations-allows-setting-a-zero-numberofweeks", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Prisma%20Finance/Prisma%20Finance%20Security%20Audit%20Report.pdf" + }, + { + "title": "Pool initialization can be front-run", + "content": "##### Description\nAfter the pool deployment https://github.com/cryptoalgebra/Algebra/blob/6c22b64977e0b0266aec89470480df74977eb606/src/core/contracts/AlgebraFactory.sol#L95, the initialize function isn't called which allows anyone to set the initial price in the pool. The price setting can affect liquidity addition in the `mint` function. Initialization can also be front-run if the pool is created from the periphery, so this problem allows a malicious user to ddos any pool.\nAlso, the `swap` function can be executed without any tokens from the `msg.sender` if it operates entirely within an interval with zero active liquidity. Concurrently, the `mint` function in the `AlgebraPool` contract does not include the `amount0Max` and `amount1Max` parameters making it vulnerable to undesirable price fluctuations. This creates a loophole that malicious actors can exploit capitalizing on price slippage to their advantage.\n\nFor clarity, consider the following sequence of events (these events can also take place after the pool creation):\n\n1. A liquidity provider (LP) initiates the `mint` transaction to the `AlgebraPool` with the current price set to `P` and the pool's actual liquidity standing at zero. The LP's intention is to set a position with the `amount0` of token0 and `amount1` of token1.\n2. An exploiter front-runs this action by performing a `swap` which shifts the price to `P' < P` undervaluing `token0`. This operation costs the exploiter nothing in terms of `token0` due to the absence of liquidity.\n3. Subsequently, the LP mints the new position acquiring `amount0' < amount0` of token0 and `amount1' > amount1` of token1.\n4. Then the exploiter conducts another `swap` acquiring `token0` and reverting its price back to the prevalent market rate capitalizing on the arbitrage window.\n5. These actions result in the LP contributing more of `token1` than it was initially planned incurring a loss.\n\nThis issue is classified as `high` severity. It offers bad actors an opportunity to exploit the lack of price slippage checks in the `mint` function. Even though conditions without `amount0Max` and `amount1Max` might be managed through the `periphery`, it still exposes the system to the near-zero cost of significant price shifts within intervals with zero active liquidity. This could potentially pave the way for DoS attacks targeting liquidity positions.\n\n##### Recommendation\nWe recommend calling the initialize function after the pool deployment in the `createPool` function. Also, we recommend implementing constraints on the `swap` function, especially when the swap ends in a non-initialized tick with zero liquidity. This will retain malicious entities from manipulating prices within intervals of zero liquidity and will limit the feasibility of DoS attacks in such scenarios. For solving the problem when the pool is initialized with a correct price but a malicious actor uses token-free swaps to move the price, we recommend adding a method that allows users to move price and add liquidity in one tx. Price moving, in this case, will be token-free because total pool liquidity will be 0.\n", + "protocol": "Algebra Finance", + "report_date": "2023-08-25", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Core/README.md#1-pool-initialization-can-be-front-run", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Core/Algebra%20Finance%20Core%20Security%20Audit%20Report.pdf" + }, + { + "title": "Ownership renouncement will grant a role to zero address", + "content": "##### Description\nAfter the ownership renouncement, the owner will be zero address, and it will be granted with `DEFAULT_ADMIN_ROLE` https://github.com/cryptoalgebra/Algebra/blob/6c22b64977e0b0266aec89470480df74977eb606/src/core/contracts/AlgebraFactory.sol#L165.\n\n##### Recommendation\nWe recommend adding a check that `owner` is not a zero address.\n\n", + "protocol": "Algebra Finance", + "report_date": "2023-08-25", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Core/README.md#1-ownership-renouncement-will-grant-a-role-to-zero-address", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Core/Algebra%20Finance%20Core%20Security%20Audit%20Report.pdf" + }, + { + "title": "A broken hook can block user funds", + "content": "##### Description\nFor closing position, a user should call the `burn` function which uses hooks to external contract https://github.com/cryptoalgebra/Algebra/blob/6c22b64977e0b0266aec89470480df74977eb606/src/core/contracts/AlgebraPool.sol#L137. If a hook were broken, then users would not be able to get the deposited funds.\n\n##### Recommendation\nWe recommend adding an emergency exit for users that can be triggered if the hook breaks.\n", + "protocol": "Algebra Finance", + "report_date": "2023-08-25", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Core/README.md#2-a-broken-hook-can-block-user-funds", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Core/Algebra%20Finance%20Core%20Security%20Audit%20Report.pdf" + }, + { + "title": "Active pool `plugin` can be modified without updating `pluginConfig`", + "content": "##### Description\nhttps://github.com/cryptoalgebra/Algebra/blob/6c22b64977e0b0266aec89470480df74977eb606/src/core/contracts/AlgebraPool.sol#L402\nAn issue has been found in the `setPlugin` function.\nPool administrators can alter the `plugin` of an active pool. However, there is a discrepancy as the `pluginConfig` of the newly-introduced `plugin` might differ from its predecessor. This could lead to invoking unimplemented hooks that were previously operational in the old `plugin`. Furthermore, if the former `plugin` employed dynamic fees set beforehand, and the succeeding plugin operates with static fees or vice versa, the pool `fee` parameter stays in an inconsistent state resulting in incorrect fee withdrawals. Additionally, when associating a `plugin` to an active `pool`, certain pre-initialization logic might be imperative, particularly when establishing the new plugin configuration, initializing internal local variables, and designating the new fee.\n\nThis vulnerability is classified as `medium` as linking a new `plugin` to the pool could temporarily block specific `pool` functionality and unintentionally trigger inappropriate `fee` actions, persisting until the correct `plugin` initialization is carried out.\n\n##### Recommendation\nWe recommend adding a hook call to the `plugin` as part of the `setPlugin` function. This inclusion should initialize the `plugin`'s local variables and concurrently define the fresh `pluginConfig` and `fees` within the `pool`.\n\n", + "protocol": "Algebra Finance", + "report_date": "2023-08-25", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Core/README.md#3-active-pool-plugin-can-be-modified-without-updating-pluginconfig", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Core/Algebra%20Finance%20Core%20Security%20Audit%20Report.pdf" + }, + { + "title": "Admin can set non-zero `pluginConfig` in `pool` with zero `plugin`", + "content": "##### Description\nhttps://github.com/cryptoalgebra/Algebra/blob/6c22b64977e0b0266aec89470480df74977eb606/src/core/contracts/AlgebraPool.sol#L431\nThe `Administrator` can set a non-zero value for `pluginConfig` while setting the `plugin` to zero. Such a configuration can potentially trigger reverts in pool functions. \nThis issue is classified as `medium`, as the combination of a non-zero `pluginConfig` with a zero `plugin` can disrupt certain functionalities of the `pool`.\n\n##### Recommendation\nIn order to ensure consistency and prevent potential disruptions, we recommend including a conditional check: `if (plugin == 0) require(pluginConfig == 0);`.\n\n", + "protocol": "Algebra Finance", + "report_date": "2023-08-25", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Core/README.md#4-admin-can-set-non-zero-pluginconfig-in-pool-with-zero-plugin", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Core/Algebra%20Finance%20Core%20Security%20Audit%20Report.pdf" + }, + { + "title": "Requires without a message", + "content": "##### Description\nThere are some `require` checks that do not contain a revert message (e.g., https://github.com/cryptoalgebra/Algebra/blob/6c22b64977e0b0266aec89470480df74977eb606/src/core/contracts/AlgebraCommunityVault.sol#L37). If some logic broke in the contract, then it would be tough to find the specific place which leads to the revert.\n\n##### Recommendation\nWe recommend adding revert messages to all `require` checks.\n\n\n", + "protocol": "Algebra Finance", + "report_date": "2023-08-25", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Core/README.md#1-requires-without-a-message", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Core/Algebra%20Finance%20Core%20Security%20Audit%20Report.pdf" + }, + { + "title": "Zero fees will reset accrued rewards", + "content": "##### Description\nIf the admin of the community vault decided to set algebra fee to 0, then all previously accumulated rewards would be lost\nhttps://github.com/cryptoalgebra/Algebra/blob/6c22b64977e0b0266aec89470480df74977eb606/src/core/contracts/AlgebraCommunityVault.sol#L79-L82.\n\n##### Recommendation\nWe recommend being aware of these fee mechanics.\n", + "protocol": "Algebra Finance", + "report_date": "2023-08-25", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Core/README.md#2-zero-fees-will-reset-accrued-rewards", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Core/Algebra%20Finance%20Core%20Security%20Audit%20Report.pdf" + }, + { + "title": "Dangerous type casting", + "content": "##### Description\nType casting here https://github.com/cryptoalgebra/Algebra/blob/6c22b64977e0b0266aec89470480df74977eb606/src/core/contracts/AlgebraPool.sol#L146 can lead to a potential loss of user funds.\n\n##### Recommendation\nWe recommend using a safe type cast there.\n", + "protocol": "Algebra Finance", + "report_date": "2023-08-25", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Core/README.md#3-dangerous-type-casting", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Core/Algebra%20Finance%20Core%20Security%20Audit%20Report.pdf" + }, + { + "title": "A flash loan fee sandwich attack", + "content": "##### Description\nhttps://github.com/cryptoalgebra/Algebra/blob/6c22b64977e0b0266aec89470480df74977eb606/src/core/contracts/AlgebraPool.sol#L328\nThe flash loan fee is spread among current active liquidity providers. A malicious actor can get a flash loan transaction from the mempool and wrap it into a sandwich:\n1. `AlgebraPool.mint()` with highly concentrated liquidity to the pool (for the current active tick with the minimal interval).\n2. A flash loan transaction from the mem pool.\n3. `AlgebraPool.burn()`.\nSo, the malicious actor will get a big amount of flash loan fee from liquidity providers.\n\n##### Recommendation\nWe recommend distributing flash loan commissions equally among all LPs.\n", + "protocol": "Algebra Finance", + "report_date": "2023-08-25", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Core/README.md#4-a-flash-loan-fee-sandwich-attack", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Core/Algebra%20Finance%20Core%20Security%20Audit%20Report.pdf" + }, + { + "title": "No parameter redundancy checks", + "content": "##### Description\n\nCertain setters in the `AlgebraCommunityVault` and `AlgebraPool` contracts are missing checks to ensure that the incoming parameter value isn't identical to the existing one. Specific instances include:\nhttps://github.com/cryptoalgebra/Algebra/blob/6c22b64977e0b0266aec89470480df74977eb606/src/core/contracts/AlgebraCommunityVault.sol#L102\nhttps://github.com/cryptoalgebra/Algebra/blob/6c22b64977e0b0266aec89470480df74977eb606/src/core/contracts/AlgebraCommunityVault.sol#L123\nhttps://github.com/cryptoalgebra/Algebra/blob/6c22b64977e0b0266aec89470480df74977eb606/src/core/contracts/AlgebraCommunityVault.sol#L134\nhttps://github.com/cryptoalgebra/Algebra/blob/6c22b64977e0b0266aec89470480df74977eb606/src/core/contracts/AlgebraPool.sol#L423.\n\n##### Recommendation\nWe recommend integrating the necessary redundancy checks into the mentioned functions to ensure no reassignment with identical values.\n\n", + "protocol": "Algebra Finance", + "report_date": "2023-08-25", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Core/README.md#5-no-parameter-redundancy-checks", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Core/Algebra%20Finance%20Core%20Security%20Audit%20Report.pdf" + }, + { + "title": "No explicit checks for `mint` and `swap` calls on uninitialized Pool", + "content": "##### Description\nhttps://github.com/cryptoalgebra/Algebra/blob/6c22b64977e0b0266aec89470480df74977eb606/src/core/contracts/AlgebraPool.sol#L66 https://github.com/cryptoalgebra/Algebra/blob/6c22b64977e0b0266aec89470480df74977eb606/src/core/contracts/AlgebraPool.sol#L210 https://github.com/cryptoalgebra/Algebra/blob/6c22b64977e0b0266aec89470480df74977eb606/src/core/contracts/AlgebraPool.sol#L253 The `swap` and `mint` functions can be invoked on an uninitialized pool, leading to a potential `revert` midway through execution due to invariant checks. This might introduce vulnerabilities if there are modifications to the implementation in subsequent updates.\n##### Recommendation\nWe recommend adding an explicit precondition to preempt the following errors: `require(globalState.price != 0)`, to the`swap`, `swapWithPaymentInAdvance`, and `mint` functions.\n\n", + "protocol": "Algebra Finance", + "report_date": "2023-08-25", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Core/README.md#6-no-explicit-checks-for-mint-and-swap-calls-on-uninitialized-pool", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Core/Algebra%20Finance%20Core%20Security%20Audit%20Report.pdf" + }, + { + "title": "Missing event emissions in `AlgebraCommunityVault`", + "content": "##### Description\nCertain setters within the `AlgebraCommunityVault` contract do not emit events upon execution. Specific instances include:\nhttps://github.com/cryptoalgebra/Algebra/blob/6c22b64977e0b0266aec89470480df74977eb606/src/core/contracts/AlgebraCommunityVault.sol#L111\nhttps://github.com/cryptoalgebra/Algebra/blob/6c22b64977e0b0266aec89470480df74977eb606/src/core/contracts/AlgebraCommunityVault.sol#L123\nhttps://github.com/cryptoalgebra/Algebra/blob/6c22b64977e0b0266aec89470480df74977eb606/src/core/contracts/AlgebraCommunityVault.sol#L129.\t \n\n##### Recommendation\nTo enhance transparency and traceability, we recommend implementing appropriate event emissions for the above-mentioned functions.\n\n\n", + "protocol": "Algebra Finance", + "report_date": "2023-08-25", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Core/README.md#7-missing-event-emissions-in-algebracommunityvault", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Core/Algebra%20Finance%20Core%20Security%20Audit%20Report.pdf" + }, + { + "title": "Users can't control upgrades in the plugin implementation", + "content": "##### Description\nPlugins can affect the number of tokens that users will receive after the swap, so updating the plugin without a time delay can negatively affect users (https://github.com/cryptoalgebra/Algebra/blob/6c22b64977e0b0266aec89470480df74977eb606/src/core/contracts/AlgebraPool.sol#L401).\n\n##### Recommendation\nWe recommend adding a time delay before updating the plugin implementation.\n", + "protocol": "Algebra Finance", + "report_date": "2023-08-25", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Core/README.md#8-users-cant-control-upgrades-in-the-plugin-implementation", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Core/Algebra%20Finance%20Core%20Security%20Audit%20Report.pdf" + }, + { + "title": "`swap` function can be executed without any tokens", + "content": "##### Description\nThe `swap` function can be executed without any tokens from the `msg.sender` if it operates entirely within an interval with zero active liquidity.\n\n##### Recommendation\nWe recommend implementing constraints on the `swap` function, especially when the swap ends in a non-initialized tick with zero liquidity.\n", + "protocol": "Algebra Finance", + "report_date": "2023-08-25", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Core/README.md#9-swap-function-can-be-executed-without-any-tokens", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Core/Algebra%20Finance%20Core%20Security%20Audit%20Report.pdf" + }, + { + "title": "EIP712 DOMAIN_SEPARATOR stored as immutable", + "content": "##### Description\nTo prevent so-called \"replay attacks\", EIP712 incorporates the chain ID into the signed data. However, the audited [code's](https://github.com/bebop-dex/bebop-smart-contracts/blob/f42cc5efe7a843bb015aec409aaa08e7643d0ca9/src/contracts/base/BebopSigning.sol#L42) EIP712 implementation uses cached values (stored as immutable variables), independent of the actual chain ID which could be returned by the `CHAINID` EVM opcode. This approach is potentially unsafe as such signatures could be deemed valid in forked networks, thus creating a vulnerability to replay attacks.\n\nWhen combined with unlimited approvals (refer to Medium.1), orders placed on one network could be \"replayed\" on a forked network without the account owner's consent.\n##### Recommendation\nTo prevent replay attacks, it is recommended to adhere to the best practices of the EIP712 implementation (refer to OpenZeppelin's EIP712.sol).\n", + "protocol": "Bebop", + "report_date": "2023-07-27", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Bebop/README.md#1-eip712-domain_separator-stored-as-immutable", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Bebop/Bebop%20Security%20Audit%20Report.pdf" + }, + { + "title": "Unjustified unlimited approvals", + "content": "##### Description\nSeveral parts of code grant unlimited `type(uint).max` approvals even when it's not justifiable:\n- https://github.com/bebop-dex/bebop-smart-contracts/blob/f42cc5efe7a843bb015aec409aaa08e7643d0ca9/src/contracts/BebopSettlement.sol#L155\n- https://github.com/bebop-dex/bebop-smart-contracts/blob/f42cc5efe7a843bb015aec409aaa08e7643d0ca9/src/contracts/base/BebopTransfer.sol#L103\n\nNo threat is inherent to it. However, it diminishes the overall contract security and could potentially be exploited by various attack vectors.\n##### Recommendation\nIt's recommended to grant approvals only for the exact amount that is anticipated to be spent.\n", + "protocol": "Bebop", + "report_date": "2023-07-27", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Bebop/README.md#1-unjustified-unlimited-approvals", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Bebop/Bebop%20Security%20Audit%20Report.pdf" + }, + { + "title": "Potentially unsafe usage of `ecrecover` return value", + "content": "##### Description\nThe `ecrecover` function may return a non-zero value even if the signature is invalid. It's unsafe to use the return value of `ecrecover` for any purpose other than comparing it with a valid signer value. Currently, these parts of the code use it as an index for the `address => boolean map`:\n- https://github.com/bebop-dex/bebop-smart-contracts/blob/f42cc5efe7a843bb015aec409aaa08e7643d0ca9/src/contracts/base/BebopSigning.sol#L119\n- https://github.com/bebop-dex/bebop-smart-contracts/blob/f42cc5efe7a843bb015aec409aaa08e7643d0ca9/src/contracts/base/BebopSigning.sol#L137\n\nWhile it's unlikely that this issue can be exploited in the current code, future modifications could potentially make the issue more severe.\n##### Recommendation\nIt is recommended to use the `ecrecover` value only for comparison with the expected value, and not as an arbitrary value.\n", + "protocol": "Bebop", + "report_date": "2023-07-27", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Bebop/README.md#2-potentially-unsafe-usage-of-ecrecover-return-value", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Bebop/Bebop%20Security%20Audit%20Report.pdf" + }, + { + "title": "Truncation of the `nonce` value", + "content": "##### Description\nIn the [`invalidateOrder`](https://github.com/bebop-dex/bebop-smart-contracts/blob/f42cc5efe7a843bb015aec409aaa08e7643d0ca9/src/contracts/base/BebopSigning.sol#L167) function, a `uint256` value is cast to `uint64`, silently ignoring higher bits of the value. This could lead to value collisions when different nonce values as `uint256` have the same values as `uint64`.\n\nAlthough the `uint64` value range is generally sufficient for the purpose of a `nonce`, and a `nonce` collision would likely cause a revert and, thus, it doesn't seem to be exploitable, the code's security could be further enhanced by addressing this issue.\n##### Recommendation\nIt's recommended to utilize as many bits of the value as possible (248 bits seems to be a reasonable approach for this code). Additionally, it's recommended to ensure that the truncated bits of the value were actually zero to prevent value collisions.\n", + "protocol": "Bebop", + "report_date": "2023-07-27", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Bebop/README.md#3-truncation-of-the-nonce-value", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Bebop/Bebop%20Security%20Audit%20Report.pdf" + }, + { + "title": "Extra msg.value could be lost", + "content": "##### Description\nThis code ensures that the passed msg.value is large enough, but it ignores any extra msg.value that's passed:\n- https://github.com/bebop-dex/bebop-smart-contracts/blob/f42cc5efe7a843bb015aec409aaa08e7643d0ca9/src/contracts/BebopSettlement.sol#L76\n- https://github.com/bebop-dex/bebop-smart-contracts/blob/f42cc5efe7a843bb015aec409aaa08e7643d0ca9/src/contracts/BebopSettlement.sol#L210\n\nAny extra value passed to the transaction will be lost by the user.\n##### Recommendation\nIt is recommended to refund the extra msg.value or to revert transactions with an unexpectedly large msg.value.\n", + "protocol": "Bebop", + "report_date": "2023-07-27", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Bebop/README.md#4-extra-msgvalue-could-be-lost", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Bebop/Bebop%20Security%20Audit%20Report.pdf" + }, + { + "title": "Consequent `WETH` `deposit`/`withdraw`", + "content": "##### Description\nIf both `nativeTokens.toMaker` and `nativeTokens.toTaker` are non-zero, the audited code will trigger a consequent `deposit` and then a `withdraw` to the `WETH`:\n- https://github.com/bebop-dex/bebop-smart-contracts/blob/f42cc5efe7a843bb015aec409aaa08e7643d0ca9/src/contracts/BebopSettlement.sol#L77-L90\n- https://github.com/bebop-dex/bebop-smart-contracts/blob/f42cc5efe7a843bb015aec409aaa08e7643d0ca9/src/contracts/BebopSettlement.sol#L211-L223\n\nIt can be simplified to a single `deposit` or `withdraw` depending on the difference between the `toMaker` and `toTaker` values.\n##### Recommendation\nIn order to optimize gas consumption, it is recommended to improve the code in accordance with the issue outlined above.\n", + "protocol": "Bebop", + "report_date": "2023-07-27", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Bebop/README.md#1-consequent-weth-depositwithdraw", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Bebop/Bebop%20Security%20Audit%20Report.pdf" + }, + { + "title": "Double voting in `Bootstrap.vy` in case of violation of time intervals", + "content": "##### Description\n\n- https://github.com/yearn/yETH-bootstrap/blob/2dd219d3af49952275934638e8c9d50d0fef0d8f/contracts/Bootstrap.vy#L423\n\nThe Bootstrap contract is deployed by the owner setting key periods using the following functions: \n- set_whitelist_period()\n- set_incentive_period()\n- set_deposit_period()\n- set_vote_period()\n- set_lock_end()\n\nThere is a scenario in which the `deposit_end` and `vote_end` parameters in the `Bootstrap` contract end up being higher than `lock_end`. This can happen, for example, if the management initially sets the correct values for the time intervals but later decides to manually extend the voting by calling `set_deposit_period()` and `set_vote_period()` with increased values, forgetting to also call `set_lock_end()`.\n\nCalling `set_deposit_period()` with increased values will work without an error because requirement `_begin >= self.whitelist_begin` will be satisfied. Calling `set_vote_period()` with increased values will also work without an error because condition `_begin >= self.deposit_begin` will be satisfied.\n\nIf `deposit_end` and `vote_end` are increased enough to be higher than `lock_end`, a hacker can call `claim()` to withdraw their funds in styETH, sell them for ETH, and vote again repeating this process multiple times. Potentially, it can be done with a flash loan if the hacker finds a place to sell styETH or yETH, for example, via a curve stable pool. By accumulating votes, the hacker can claim 99.99% of all incentives from winning projects.\n\n##### Recommendation\n\nIt is recommended to check invariant `vote_end < lock_end` in the `set_vote_period()` function.\n", + "protocol": "Yearn Finance", + "report_date": "2023-07-11", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/yETH-bootstrap/README.md#1-double-voting-in-bootstrapvy-in-case-of-violation-of-time-intervals", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/yETH-bootstrap/Yearn%20Finance%20yETH-bootstrap%20Security%20Audit%20Report.pdf" + }, + { + "title": "Votes for cancelled protocols are lost", + "content": "##### Description\n\n- https://github.com/yearn/yETH-bootstrap/blob/2dd219d3af49952275934638e8c9d50d0fef0d8f/contracts/Bootstrap.vy#L453\n\nIf the management calls `undo_whitelist()` for a protocol in `Bootstrap.vy` that users have already voted for, these users will not be able to reallocate their canceled votes to other projects.\n\n##### Recommendation\n\nIt is recommended to add a function that allows users to call off their votes for a canceled project.\n", + "protocol": "Yearn Finance", + "report_date": "2023-07-11", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/yETH-bootstrap/README.md#2-votes-for-cancelled-protocols-are-lost", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/yETH-bootstrap/Yearn%20Finance%20yETH-bootstrap%20Security%20Audit%20Report.pdf" + }, + { + "title": "CurveLP setters should not be used to update pools if the previous liquidity is not withdrawn yet", + "content": "##### Description\n\nCurveLP stores key pool addresses - deposits, withdrawals and approvals are deterministic to these pool. \nBut, for example, if the management calls `set_pool()` with the new pool, the operator will not be able to withdraw liquidity from the previous pool.\n\nThe are multiple of such setters:\n- https://github.com/yearn/yETH-bootstrap/blob/2dd219d3af49952275934638e8c9d50d0fef0d8f/contracts/modules/CurveLP.vy#L216\n- https://github.com/yearn/yETH-bootstrap/blob/2dd219d3af49952275934638e8c9d50d0fef0d8f/contracts/modules/CurveLP.vy#L270\n- https://github.com/yearn/yETH-bootstrap/blob/2dd219d3af49952275934638e8c9d50d0fef0d8f/contracts/modules/CurveLP.vy#L320\n- https://github.com/yearn/yETH-bootstrap/blob/2dd219d3af49952275934638e8c9d50d0fef0d8f/contracts/modules/CurveLP.vy#L349\n- https://github.com/yearn/yETH-bootstrap/blob/2dd219d3af49952275934638e8c9d50d0fef0d8f/contracts/modules/CurveLP.vy#L428\n\n##### Recommendation\n\nWe recommend checking that the previous pool does not have liquidity or allowing withdrawal from any pool and setting restriction only for new deposits.\n", + "protocol": "Yearn Finance", + "report_date": "2023-07-11", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/yETH-bootstrap/README.md#3-curvelp-setters-should-not-be-used-to-update-pools-if-the-previous-liquidity-is-not-withdrawn-yet", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/yETH-bootstrap/Yearn%20Finance%20yETH-bootstrap%20Security%20Audit%20Report.pdf" + }, + { + "title": "Multiple ways for the management to mint any amount of yETH not backed by real ETH", + "content": "##### Description\n\nThe POL contract seems to manage yETH minting, even for management and modules. But current limitations are easily avoidable.\n\nFirst option. The management can:\n1) send 10 ETH to `POL.__default__()`.\n`self.available` is 10 ETH now.\n2) call send back 10 ETH to management calling `POL.send_native()`.\n`self.available` is not updated and remain 10 ETH.\n3) send received 10 ETH to `POL.__default__()`.\n`self.available` is 20 ETH now.\n\nAs a result, 10 ETH was used to set `self.available` as 20 ETH. The management can mint 20 yETH backed by only 10 ETH.\n\nSecond option, an easier one. The management can:\n1) flashloan X ETH\n2) send X ETH to `POL.__default__()`\n`self.available` is set to X ETH.\n3) call `POL.send_native()` to withdraw X ETH\n4) repay X ETH flashloan\n\nAs a result, `self.available` is set to any amount X with little cost and in one transaction.\n\n##### Recommendation\n\nThe current version of `self.available` does not set any restrictions and the whole contract does not control the backing of minted yETH.\n\nWe recommend some options:\n1) checking that this behavior is intended (`self.available` can be dropped in this case)\n2) adding the `self.available` decrease on ETH withdrawal\n3) redesigning the control of yETH backing.\n", + "protocol": "Yearn Finance", + "report_date": "2023-07-11", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/yETH-bootstrap/README.md#1-multiple-ways-for-the-management-to-mint-any-amount-of-yeth-not-backed-by-real-eth", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/yETH-bootstrap/Yearn%20Finance%20yETH-bootstrap%20Security%20Audit%20Report.pdf" + }, + { + "title": "An economic attack allowing protocols to bribe voters more effectively", + "content": "##### Description\n\nAll voters receive the incentive from the winner protocol despite the direction of their votes. Voters can vote for random protocols and still receive rewards from winners. Some economic attacks are allowed:\n\n1) Protocol A bribes Voters A outside the Bootstrap. 10k USD are put on some external contract and distributed among Voters A only if Protocol A is a winner.\n2) Protocol A does not put 10k USD as incentive to Bootstrap. But Protocol B gives 10k USD to Bootstrap.\n3) Voters A vote their 50% for Protocol A. Voters B vote their 50% for Protocol B. All protocols are winners.\n4) Claiming happens:\n\nVoters A receive 10k USD from Protocol A on the external contract + 5k USD from Protocol B = 15k USD\nVoters B receive 5k USD from Protocol B.\n\nAs a result, Protocol A arranged additional profits for their Voters A stealing rewards from Voters B.\n\n##### Recommendation\n\nOnly management decides which protocols are the winners and takes into account potential vote bypasses. Therefore, with monitoring, such attacks won't work.\n", + "protocol": "Yearn Finance", + "report_date": "2023-07-11", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/yETH-bootstrap/README.md#2-an-economic-attack-allowing-protocols-to-bribe-voters-more-effectively", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/yETH-bootstrap/Yearn%20Finance%20yETH-bootstrap%20Security%20Audit%20Report.pdf" + }, + { + "title": "A variable is not used", + "content": "##### Description\n\n`POL_SPLIT` is not used.\n- https://github.com/yearn/yETH-bootstrap/blob/2dd219d3af49952275934638e8c9d50d0fef0d8f/contracts/Bootstrap.vy#LL125C1-L125C10\n\nIt was likely designed to calculate the funds split between treasury and POL during `split()`.\n\n##### Recommendation\n\nWe recommend removing this constant.\n", + "protocol": "Yearn Finance", + "report_date": "2023-07-11", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/yETH-bootstrap/README.md#3-a-variable-is-not-used", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/yETH-bootstrap/Yearn%20Finance%20yETH-bootstrap%20Security%20Audit%20Report.pdf" + }, + { + "title": "The yETH contract has one step for management role transferring and allows zero address as management", + "content": "##### Description\n\nThe function does not use a two-step process for management role transferring.\n- https://github.com/yearn/yETH-bootstrap/blob/2dd219d3af49952275934638e8c9d50d0fef0d8f/contracts/Token.vy#L125-L131\n\nBut other contracts use a two-step process with the pending_management role.\n- https://github.com/yearn/yETH-bootstrap/blob/2dd219d3af49952275934638e8c9d50d0fef0d8f/contracts/POL.vy#L125-L147\n\n##### Recommendation\n\nWe recommend using the same process of management role transferring as on other contracts (with the pending_management).\n", + "protocol": "Yearn Finance", + "report_date": "2023-07-11", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/yETH-bootstrap/README.md#4-the-yeth-contract-has-one-step-for-management-role-transferring-and-allows-zero-address-as-management", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/yETH-bootstrap/Yearn%20Finance%20yETH-bootstrap%20Security%20Audit%20Report.pdf" + }, + { + "title": "The Bootstrap.repay() function is likely supposed to be called by protocol addresses only, but it is public and just burns tokens", + "content": "##### Description\n\nrepay() takes yETH tokens and burn them, giving nothing in return.\n- https://github.com/yearn/yETH-bootstrap/blob/2dd219d3af49952275934638e8c9d50d0fef0d8f/contracts/Bootstrap.vy#L262-L271\n\n\nIt is used in the Shutdown contract as a part of a multi-step logic.\n- https://github.com/yearn/yETH-bootstrap/blob/2dd219d3af49952275934638e8c9d50d0fef0d8f/contracts/modules/Shutdown.vy#L47-L58\n\nThis function is available for all users and it is not obvious that it results in just losing funds.\n\n##### Recommendation\n\nWe recommend shortlisting addresses allowed to call this function.\n", + "protocol": "Yearn Finance", + "report_date": "2023-07-11", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/yETH-bootstrap/README.md#5-the-bootstraprepay-function-is-likely-supposed-to-be-called-by-protocol-addresses-only-but-it-is-public-and-just-burns-tokens", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/yETH-bootstrap/Yearn%20Finance%20yETH-bootstrap%20Security%20Audit%20Report.pdf" + }, + { + "title": "Rebase and deflationary tokens used as incentive can get stuck on the Bootstrap contract", + "content": "##### Description\n\nThe Bootstrap contract for incentives stores the amount of tokens \"to be transferred\", but not the amount which can be sent later.\n\n- https://github.com/yearn/yETH-bootstrap/blob/2dd219d3af49952275934638e8c9d50d0fef0d8f/contracts/Bootstrap.vy#L168-L183\n\nAs a result, claim_incentive() and refund_incentive() can leave some tokens stuck on the contract if Bootstrap does not have enough balance for transfers.\n- https://github.com/yearn/yETH-bootstrap/blob/2dd219d3af49952275934638e8c9d50d0fef0d8f/contracts/Bootstrap.vy#L300-L338\n\n##### Recommendation\n\nWe recommend adding the list of allowed tokens in the documentation or accept the risk that some tokens can get stuck.\n", + "protocol": "Yearn Finance", + "report_date": "2023-07-11", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/yETH-bootstrap/README.md#6-rebase-and-deflationary-tokens-used-as-incentive-can-get-stuck-on-the-bootstrap-contract", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/yETH-bootstrap/Yearn%20Finance%20yETH-bootstrap%20Security%20Audit%20Report.pdf" + }, + { + "title": "The `operator` can make an approve to the zero address", + "content": "##### Description\n\n- https://github.com/yearn/yETH-bootstrap/blob/2dd219d3af49952275934638e8c9d50d0fef0d8f/contracts/modules/CurveLP.vy#L232\n\nThe operator can make an extra approve to the zero address.\n\n##### Recommendation\n\nWe recommend adding the following check:\n\n```\nassert self.pool != empty(address)\n```\n", + "protocol": "Yearn Finance", + "report_date": "2023-07-11", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/yETH-bootstrap/README.md#7-the-operator-can-make-an-approve-to-the-zero-address", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/yETH-bootstrap/Yearn%20Finance%20yETH-bootstrap%20Security%20Audit%20Report.pdf" + }, + { + "title": "Add an additional event", + "content": "##### Description\n\nThere is no event for the change of `convex_pool_id`:\n- https://github.com/yearn/yETH-bootstrap/blob/2dd219d3af49952275934638e8c9d50d0fef0d8f/contracts/modules/CurveLP.vy#L336\n\n##### Recommendation\n\nWe recommend adding a new event for `convex_pool_id`.\n", + "protocol": "Yearn Finance", + "report_date": "2023-07-11", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/yETH-bootstrap/README.md#8-add-an-additional-event", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/yETH-bootstrap/Yearn%20Finance%20yETH-bootstrap%20Security%20Audit%20Report.pdf" + }, + { + "title": "Unrestricted access to the `setVibeFees` function in `MintSaleBase`", + "content": "##### Description\nThe `setVibeFees` function within the `MintSaleBase` contract is protected by the `onlyMasterContractOwner` modifier. However, anyone can call this function if the contract is the implementation contract itself, meaning it has no master contract. An exploiter via this vulnerability can monitor the deployment transactions of the `MintSaleBase` inheritor contracts and submit their transaction before deployment, thereby setting the `vibeTreasury` field to their address and arbitrarily increasing the value of the `feeTake` field. Consequently, the owner of the `masterContract` must reset the values back and re-establish the `fee` parameters of the affected copy.\n\n##### Recommendation\nWe recommend adding the following require statement to the `onlyMasterContractOwner` modifier that verifies if the contract doesn't have a master contract. In such cases, only the owner of the contract should be allowed to pass this modifier. We propose adding the following line here: [https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/mint/MintSaleBase.sol#L69]\n```solidity\nrequire(msg.sender == owner())\n```\n\n***\n", + "protocol": "Vibe", + "report_date": "2023-06-30", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/README.md#1-unrestricted-access-to-the-setvibefees-function-in-mintsalebase", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/Vibe%20Security%20Audit%20Report.pdf" + }, + { + "title": "Potential reinitialization of the `VibeERC721` contract", + "content": "##### Description\nThe `baseURI` field can be set to an empty string using the `changeBaseURI` function https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/tokens/VibeERC721.sol#L223. It allows to call the `init` function by anyone and subsequently claim the ownership of the entire `VibeERC721` contract https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/tokens/VibeERC721.sol#L79.\n\n##### Recommendation\nWe recommend adding the following check to the `changeBaseURI` function:\n`require(bytes(baseURI)_.length != 0);`\n\n***\n", + "protocol": "Vibe", + "report_date": "2023-06-30", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/README.md#1-potential-reinitialization-of-the-vibeerc721-contract", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/Vibe%20Security%20Audit%20Report.pdf" + }, + { + "title": "`NFTMintSaleMultiple` won't work if other minter mints tokens with an id intersected with the id range on sale", + "content": "##### Description\nIf an external minter of `nft` mints a token with an id that falls within the range of ids specified for sale, the functionality of `NFTMintSaleMultiple` can be disrupted. When such an intersecting mint occurs, the `buyNFT` function will fail to execute as the `nft.mintWithId(recipient, id)` https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/mint/NFTMintSaleMultiple.sol#L77 call will revert due to the conflicting id.\n\n##### Recommendation\nWe recommend allowing to use only `mint` or `mintWithId` in a specific instance of the VibeERC721 contract.\n", + "protocol": "Vibe", + "report_date": "2023-06-30", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/README.md#2-nftmintsalemultiple-wont-work-if-other-minter-mints-tokens-with-an-id-intersected-with-the-id-range-on-sale", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/Vibe%20Security%20Audit%20Report.pdf" + }, + { + "title": "Lack of checks in the `setVibesFee` function", + "content": "##### Description\nThe `setVibesFee` function currently lacks checks to ensure that the `vibeTreasury_` parameter is not set to the zero address and that the `feeTake_` parameter does not exceed the `BPS`. It can potentially lead to a DoS scenario if these parameters are mistakenly set in such a way.\n\n##### Recommendation\nWe recommend setting the following checks within the `setVibesFee` function https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/mint/MintSaleBase.sol#L76:\n```solidity\nrequire(vibeTreasury_ != address(0));\nrequire(feeTake_ <= BPS);\n```\n***\n", + "protocol": "Vibe", + "report_date": "2023-06-30", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/README.md#1-lack-of-checks-in-the-setvibesfee-function", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/Vibe%20Security%20Audit%20Report.pdf" + }, + { + "title": "Lack of checks in the `init` function of `NFTMintSale` and `NFTMintSaleMultiple` contracts", + "content": "##### Description\nThe `init` function in both the `NFTMintSale` and `NFTMintSaleMultiple` contracts currently lacks checks to prevent certain scenarios that can lead to unintended consequences. Firstly, there is no check to ensure that the `proxy` argument is not set to the zero address which can potentially lead to the reinitalization of the contract with the complete loss of ownership. Additionally, there are no checks to verify that `endTime >= beginTime` and that `beginTime > block.timestamp`. These checks are essential to maintain the integrity of the contract and prevent violations of the specified invariants.\n\n##### Recommendation\nWe recommend implementing the stated checks within the `init` function of both the `NFTMintSale` https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/mint/NFTMintSale.sol#L31 and `NFTMintSaleMultiple` https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/mint/NFTMintSaleMultiple.sol#L30 contracts.\n\n***\n", + "protocol": "Vibe", + "report_date": "2023-06-30", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/README.md#2-lack-of-checks-in-the-init-function-of-nftmintsale-and-nftmintsalemultiple-contracts", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/Vibe%20Security%20Audit%20Report.pdf" + }, + { + "title": "External mints affect the number of tokens available for sale in `NFTMintSale`", + "content": "##### Description\nIf an external minter of `nft` mints a token, it affects the `nft.totalSupply()` value, reducing the number of available tokens for sale in the `NFTMintSale` contract.\n\n##### Recommendation\nWe recommend using a local counter of minted tokens within the `NFTMintSale` contract instead of relying solely on the `nft.totalSupply()` https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/mint/NFTMintSale.sol#L59. This approach will prevent interference between external mints and the availability of tokens for sale.\n", + "protocol": "Vibe", + "report_date": "2023-06-30", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/README.md#3-external-mints-affect-the-number-of-tokens-available-for-sale-in-nftmintsale", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/Vibe%20Security%20Audit%20Report.pdf" + }, + { + "title": "Lack of checks on the payed amount in `buyNFT` and `buyMultipleNFT` functions if `paymentToken` is `WETH`", + "content": "##### Description\nThe `buyNFT` and `buyMultipleNFT` functions currently lack checks to verify that `msg.value` matches the expected payment amount when the `paymentToken` is set to `WETH`. If users accidentally send more ether than the intended payment amount, the funds that exceed the payment amount will be locked within the contract forever, as there is no mechanism to redeem ether from the contract.\n\n##### Recommendation\nWe recommend adding the following checks to `buyNFT` (https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/mint/NFTMintSale.sol#L69,\n https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/mint/NFTMintSaleMultiple.sol#L76) \nand `buyMultipleNFT` (https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/mint/NFTMintSale.sol#L80,\nhttps://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/mint/NFTMintSaleMultiple.sol#L86) functions:\n```solidity=\nif (paymentToken == WETH) {\n require(msg.value == payedAmount)\n} else {\n require(msg.value == 0)\n}\n```\nHere, the `payedAmount` is the sum of prices for the tokens being purchased.\n\n***\n", + "protocol": "Vibe", + "report_date": "2023-06-30", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/README.md#4-lack-of-checks-on-the-payed-amount-in-buynft-and-buymultiplenft-functions-if-paymenttoken-is-weth", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/Vibe%20Security%20Audit%20Report.pdf" + }, + { + "title": "Lack of checks in the `setMerkleTree` function of `NFTMintSaleWhitelistingMultiple`", + "content": "##### Description\n\nThe `setMerkleTree` function in the `NFTMintSaleWhitelistingMultiple` contract currently lacks checks to ensure that the `merkleRoot` values are set for all tiers. It allows the contract owner to accidentally set the `merkleRoot` of higher tiers to `bytes32(0)`, effectively allowing anyone to mint up to the `NON_WHITELISTED_MAX_PER_USER` amount of tokens from those tiers.\n\n##### Recommendation\nWe recommend adding the following check within `setMerkleRoot` https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/mint/NFTMintSaleWhitelistingMultiple.sol#L28 function:\n```solidity=\nrequire(\n merkleRoot_.length == tiers.length && \n merkleRoot_.length == externalURI_.length\n);\n```\nIt ensures that the `merkleRoot` values are set intentionally for all the tiers.\n", + "protocol": "Vibe", + "report_date": "2023-06-30", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/README.md#5-lack-of-checks-in-the-setmerkletree-function-of-nftmintsalewhitelistingmultiple", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/Vibe%20Security%20Audit%20Report.pdf" + }, + { + "title": "Lack of checks of tier range in the `init` function of the `NFTMintSaleMultiple` contract", + "content": "##### Description\nThe `init` function within the `NFTMintSaleMultiple` contract currently verifies that the id ranges of different tiers do not intersect with each other and appear in increasing order. However, there is a missing check for the last tier with index `0`.\nhttps://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/mint/NFTMintSaleMultiple.sol#L62\n\n##### Recommendation\nWe recommend adding a corresponding check for the last tier in the `init` function of the `NFTMintSaleMultiple` contract.\n\n***\n", + "protocol": "Vibe", + "report_date": "2023-06-30", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/README.md#6-lack-of-checks-of-tier-range-in-the-init-function-of-the-nftmintsalemultiple-contract", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/Vibe%20Security%20Audit%20Report.pdf" + }, + { + "title": "Lack of checks within the `init` function of `RoyaltyReceiver`", + "content": "##### Description\nThe `init` function within the `RoyaltyReceiver` contract currently lacks a check to ensure that the lengths of the `recipients_` and `recipientsBPS_` arrays are equal. It leaves the contract exposed to a potential DoS until the owner of the contract calls `setRecipientsAndBPS` again to rectify the mismatched lengths.\n\n##### Recommendation\nWe recommend adding a check within the init function to verify that `recipients_.length == recipientsBPS_.length`.\nhttps://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/RoyaltyReceiver.sol#L19\n\n***\n", + "protocol": "Vibe", + "report_date": "2023-06-30", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/README.md#7-lack-of-checks-within-the-init-function-of-royaltyreceiver", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/Vibe%20Security%20Audit%20Report.pdf" + }, + { + "title": "Ownership is not set in `createERC721` in some cases", + "content": "##### Description\nThe user can call the `createERC721` function declared here - https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/VibeFactory.sol#L352. If the user set the `owner` parameter to `address(0)` then `SimpleFactory` would own the `VibeERC721` contract and anyone would be able to trigger `transferOwnership` here - https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/SimpleFactory.sol#L35. If the user wanted to transfer ownership to themself in the second step, then their second transaction could be frontrunned by an attacker, a new minter can be set and then ownership can be given back to `SimpleFactory` so that users tx would succeed.\n\n##### Recommendation\nWe recommend transferring ownership to `msg.sender` in the `createERC721` function if the `owner` parameter is equal to `address(0)`. There are cases when `createERC721` is intentionally called with `address(0)` to leave `factory` as an owner for future initialization. Instead of `address(0)` - `address(factory)` can be passed.\n", + "protocol": "Vibe", + "report_date": "2023-06-30", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/README.md#8-ownership-is-not-set-in-createerc721-in-some-cases", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/Vibe%20Security%20Audit%20Report.pdf" + }, + { + "title": "Royalty parameters are not checked", + "content": "##### Description\nRoyalty parameters are used to calculate how much fees should be paid to the royalty receiver https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/tokens/VibeERC721.sol#L205-L210. If `royaltyRate_` is greater than `BPS` then royalty payment will revert.\n\n##### Recommendation\nWe recommend adding checks for royalty parameters.\n\n***\n", + "protocol": "Vibe", + "report_date": "2023-06-30", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/README.md#9-royalty-parameters-are-not-checked", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/Vibe%20Security%20Audit%20Report.pdf" + }, + { + "title": "`OPERATOR_FILTER_REGISTRY` can be missing in a new network", + "content": "##### Description\n`VibeERC721` contract uses `onlyAllowedOperatorApproval` and `onlyAllowedOperator` modifiers that required deployed `OPERATOR_FILTER_REGISTRY` for correct work https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/tokens/VibeERC721.sol#L132 But it can be not deployed on a new networks.\n\n##### Recommendation\nWe recommend adding a check that `OPERATOR_FILTER_REGISTRY` is deployed on the network that will be used for the protocol deployment.\n", + "protocol": "Vibe", + "report_date": "2023-06-30", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/README.md#10-operator_filter_registry-can-be-missing-in-a-new-network", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/Vibe%20Security%20Audit%20Report.pdf" + }, + { + "title": "`NON_WHITELISTED_MAX_PER_USER` of `NFTMintSaleWhitelistingMultiple` is shared between the tiers", + "content": "##### Description\nThe `NON_WHITELISTED_MAX_PER_USER` parameter is currently shared across all tiers in the `NFTMintSaleWhitelistingMultiple` contract https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/mint/NFTMintSaleWhitelistingMultiple.sol#L53. This means that non-whitelisted users are allowed to purchase the same maximum amount of tokens for each tier.\n\n##### Recommendation\nWe recommend modifying the parameter `NON_WHITELISTED_MAX_PER_USER` to be an array that describes the maximum amount of tokens non-whitelisted users are allowed to mint for each tier.\n", + "protocol": "Vibe", + "report_date": "2023-06-30", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/README.md#1-non_whitelisted_max_per_user-of-nftmintsalewhitelistingmultiple-is-shared-between-the-tiers", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/Vibe%20Security%20Audit%20Report.pdf" + }, + { + "title": "Unused variables", + "content": "##### Description\n`masterNFT` within `MintSaleBase` https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/mint/MintSaleBase.sol#LL41C15-L41C15 is unused.\n\n##### Recommendation\nWe recommend removing the `masterNFT` variable.\n\n***\n", + "protocol": "Vibe", + "report_date": "2023-06-30", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/README.md#2-unused-variables", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/Vibe%20Security%20Audit%20Report.pdf" + }, + { + "title": "Lack of event emission in setter functions", + "content": "##### Description\nThe following setter functions do not emit any events:\n* `setVibesFee` within `NFTMintSaleBase` https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/mint/MintSaleBase.sol#L76,\n* `setMerkleRoot` within `NFTMintSaleWhitelisting` https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/mint/NFTMintSaleWhitelisting.sol#L26,\n* `setMerkleRoot` within `NFTMintSaleWhitelistingMultiple` https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/mint/NFTMintSaleWhitelistingMultiple.sol#L27.\n##### Recommendation\nWe recommend adding `emit event` statements within the listed functions.\n\n***\n", + "protocol": "Vibe", + "report_date": "2023-06-30", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/README.md#3-lack-of-event-emission-in-setter-functions", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/Vibe%20Security%20Audit%20Report.pdf" + }, + { + "title": "`paymentToken` argument within the `getPayment` function can be removed", + "content": "##### Description\nThe `getPayment` internal function within the `NFTMintSaleBase` contract currently includes the `paymentToken` argument https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/mint/MintSaleBase.sol#L80. All the occurrences of this function are called with the value of`paymentToken` field of the `NFTMintSaleBase` contract.\n\n##### Recommendation\nWe recommend removing the `paymentToken` argument from the `getPayment` function.\n\n***\n", + "protocol": "Vibe", + "report_date": "2023-06-30", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/README.md#4-paymenttoken-argument-within-the-getpayment-function-can-be-removed", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/Vibe%20Security%20Audit%20Report.pdf" + }, + { + "title": "Unused function parameter", + "content": "##### Description\nAt line https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/RoyaltyReceiver.sol#L64 the `distribute` function is declared. It has an `amount` as an input parameter, but its value is never used.\n\n##### Recommendation\nWe recommend removing the `amount` parameter and not passing the `total - fee` value here - https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/mint/MintSaleBase.sol#L99.\n\n***\n", + "protocol": "Vibe", + "report_date": "2023-06-30", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/README.md#5-unused-function-parameter", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/Vibe%20Security%20Audit%20Report.pdf" + }, + { + "title": "Repetition of time range checks in the `buyMultipleNFT` functions", + "content": "##### Description\nThe `buyMultipleNFT` function in both the `NFTMintSale` and `NFTMintSaleMultiple` contracts currently calculates check that the sale is still ongoing multiple times. It results in redundant calculations of the same expression https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/mint/NFTMintSale.sol#L59, https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/mint/NFTMintSaleMultiple.sol#L75.\n\n##### Recommendation\nWe recommend moving this time range check to the beginning of the corresponding `buyNFT` and `buyMultipleNFT` functions ensuring this check is performed only once and refactoring the base logic of the `buyNFT` function of the `NFTMintSaleMultiple` contract to the internal `_buyNFT` function.\n\n***\n", + "protocol": "Vibe", + "report_date": "2023-06-30", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/README.md#6-repetition-of-time-range-checks-in-the-buymultiplenft-functions", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/Vibe%20Security%20Audit%20Report.pdf" + }, + { + "title": "Multiple `getPayment` calls within the `buyMultipleNFT` function of `NFTMintSaleMultiple` can be simplified", + "content": "##### Description\nThe `buyMultipleNFT` function in the `NFTMintSaleMultiple` contract currently makes multiple calls to `buyNFT` in a loop https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/mint/NFTMintSaleMultiple.sol#L84, which results in multiple calls to `getPayment` for each minted token. This can be simplified by using an accumulator variable to keep track of the total price of the minted tokens. With this accumulator sum, you can make a single call to the `getPayment` function after all the tokens have been minted.\n\n##### Recommendation\nWe recommend using one `getPayment` call here using the accumulator sum variable representing the total sum price.\n\n***\n", + "protocol": "Vibe", + "report_date": "2023-06-30", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/README.md#7-multiple-getpayment-calls-within-the-buymultiplenft-function-of-nftmintsalemultiple-can-be-simplified", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/Vibe%20Security%20Audit%20Report.pdf" + }, + { + "title": "The `NON_WHITELISTED_MAX_PER_USER` parameter is taking effect only if `merkleRoot` is not set", + "content": "##### Description\nThe current implementation of the `_preBuyCheck` function in the `NFTMintSaleWhitelisting` contract relies on the `merkleRoot` being set to `bytes32(0)` to make the `NON_WHITELISTED_MAX_PER_USER` parameter the maximum limit of tokens to mint https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/mint/NFTMintSaleWhitelisting.sol#L40. This means that if the `merkleRoot` is set, the `NON_WHITELISTED_MAX_PER_USER` parameter has no effect, making it impossible to create a sale that allows whitelisted users to have a different maximum mint amount than non-whitelisted users.\n\n##### Recommendation\nWe recommend adjusting the `require` statement within the `_preBuyCheck` functions (https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/mint/NFTMintSaleWhitelisting.sol#L33,\nhttps://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/mint/NFTMintSaleWhitelistingMultiple.sol#L36) as follows:\n\n```solidity\nrequire(\n claimed[msg.sender].claimed < claimed[msg.sender].max ||\n claimed[msg.sender].claimed < NON_WHITELISTED_MAX_PER_USER\n);\n```\nWith this adjustment, the `require` statement ensures that a user can buy up to the `NON_WHITELISTED_MAX_PER_USER` amount of NFT tokens if they haven't called `initUser`. This change allows for more fine-grained control over the maximum mint amount for whitelisted and non-whitelisted users.\n\nAfter making this adjustment, the `else` branch in the `initUser` function becomes redundant and can be removed (https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/mint/NFTMintSaleWhitelisting.sol#L50,\nhttps://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/mint/NFTMintSaleWhitelistingMultiple.sol#L53). Additionally, this change allows the owner of the sale to set `NON_WHITELISTED_MAX_PER_USER` to `0` if they don't want to sell tokens to non-whitelisted users.\n", + "protocol": "Vibe", + "report_date": "2023-06-30", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/README.md#8-the-non_whitelisted_max_per_user-parameter-is-taking-effect-only-if-merkleroot-is-not-set", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/Vibe%20Security%20Audit%20Report.pdf" + }, + { + "title": "Inconsistent order of `name` and `symbol` arguments in creation functions", + "content": "##### Description\nThe order of the `name` and `symbol` arguments in the creation functions of the `VibeFactory` contract (`createERC721` https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/VibeFactory.sol#L353, `createNFTMintSaleMultiple` https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/VibeFactory.sol#L279, `createNFTMintSaleMultipleWhitelisting` https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/VibeFactory.sol#L238, `createNFTMintSaleWhitelisting` https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/VibeFactory.sol#L165, `createNFTMintSale` https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/VibeFactory.sol#L120) differs, causing potential confusion for users who interact with these functions. Since both arguments have the same type, inconsistent ordering may lead to unintended parameter assignments and mistakes.\n\n##### Recommendation\nWe recommend using the same order for the `name` and `symbol` arguments in all the creation functions of the `VibeFactory` contract.\n", + "protocol": "Vibe", + "report_date": "2023-06-30", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/README.md#9-inconsistent-order-of-name-and-symbol-arguments-in-creation-functions", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/Vibe%20Security%20Audit%20Report.pdf" + }, + { + "title": "`SimpleFactory` can be drained out of ether", + "content": "##### Description\nThe `SimpleFactory` contract inherits from `BoringFactory` and `BoringBatchable`. `BoringBatchable` acts as a multicall and `BoringFactory` uses `msg.value` inside the `deploy` function. It is possible for `SimpleFactory` to store ether as it has an `exec` function which is not `payable`, but uses `value` with a call. An attacker can provide their contract to the `deploy` function and create multiple deployments using `batch`. Together with a batch attacker can provide a small `msg.value` which will be duplicated inside the `deploy` function on `init`. The attackers' contract would send the `msg.value` amount to a pre-defined address in the `init` function. It will lead to `SimpleFactory` being drained out of funds.\n\n##### Recommendation\nWe recommend changing the `exec` function and making it `payable` here - https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/SimpleFactory.sol#L39 so that in future there is no need to pre-fund `SimpleFactory` with ether.\n\n***\n", + "protocol": "Vibe", + "report_date": "2023-06-30", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/README.md#10-simplefactory-can-be-drained-out-of-ether", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/Vibe%20Security%20Audit%20Report.pdf" + }, + { + "title": "Dust can be left on the contract because of the rounding", + "content": "##### Description\nAt line https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/RoyaltyReceiver.sol#L58 transferrable `amount` is calculated based on `totalAmount` and pre-defined `recipientBPS[i]`. In some cases, there will be a residue here `totalAmount * recipientBPS[i] / BPS` which will be stuck in the contract.\n\n##### Recommendation\nWe recommend sending dust to any of the recipients.\n", + "protocol": "Vibe", + "report_date": "2023-06-30", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/README.md#11-dust-can-be-left-on-the-contract-because-of-the-rounding", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/Vibe%20Security%20Audit%20Report.pdf" + }, + { + "title": "Unnecessary inheritance from `Ownable`", + "content": "##### Description\n`NFTMintSale` and `NFTMintSaleMultiple` contracts are inherited from `MintSaleBase` and `Ownable`. But `MintSaleBase` is already inherited from `Ownable`. \n\n##### Recommendation\nWe recommend removing unnecessary inheritance from `Ownable` in `NFTMintSale` and `NFTMintSaleMultiple` contracts.\n\n***\n", + "protocol": "Vibe", + "report_date": "2023-06-30", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/README.md#12-unnecessary-inheritance-from-ownable", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/Vibe%20Security%20Audit%20Report.pdf" + }, + { + "title": "Missing zero address and zero total checks in `claimEarnings`", + "content": "##### Description\nThere is a `claimEarnings` function here - https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/mint/MintSaleBase.sol#LL88C14-L88C27. It accepts the `proceedRecipient` address as a parameter and uses the `total` variable which represents the contract balance in pre-defined `paymentToken`. In cases when the `total` is zero ,`claimEarnings` call would still be completed. Also, it is possible to transfer funds to a zero address. \n\n##### Recommendation\nWe recommend adding checks that `proceedRecipient` is not a zero address and `total` is not equal to zero.\n\n***\n", + "protocol": "Vibe", + "report_date": "2023-06-30", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/README.md#13-missing-zero-address-and-zero-total-checks-in-claimearnings", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/Vibe%20Security%20Audit%20Report.pdf" + }, + { + "title": "`renounceMinter` can be called by anyone", + "content": "##### Description\nThe `renounceMinter` function is declared here - https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/tokens/VibeERC721.sol#L68. That function can be called by anyone and it emits the `LogMinterChange` event. Such events can be misleading for some external tools.\n\n##### Recommendation\nWe recommend adding the `require(isMinter[msg.sender])` check at the beginning of the function. It will ensure that the caller is an actual minter.\n\n***\n", + "protocol": "Vibe", + "report_date": "2023-06-30", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/README.md#14-renounceminter-can-be-called-by-anyone", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/Vibe%20Security%20Audit%20Report.pdf" + }, + { + "title": "The missing check for `newEndTime`", + "content": "##### Description\nThere is an `extendEndTime` function here - https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/mint/MintSaleBase.sol#L124. It allows contract owner to set new `endTime` for sale. But there is no check that `newEndTime` is bigger than `beginTime`. `beginTime` may be in the future, so it is possible to make a mistake.\n\n##### Recommendation\nWe recommend adding a check that `newEndTime` is bigger than `beginTime`. Also, check that `nft.isMinter(address(this)) == true` can be added to exclude cases when the current minter was renounced.\n\n***\n", + "protocol": "Vibe", + "report_date": "2023-06-30", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/README.md#15-the-missing-check-for-newendtime", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/Vibe%20Security%20Audit%20Report.pdf" + }, + { + "title": "`totalSupply` doesn't represent the actual token supply", + "content": "##### Description\nThe `totalSupply` variable is used here - https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/tokens/VibeERC721.sol#L87. It helps to define the next minted token id. But in cases of `burn` or `mintWithId` that variable doesn't represent actual total token supply. \n\n##### Recommendation\nWe recommend using different naming for the variable which is used to define the next token id.\n", + "protocol": "Vibe", + "report_date": "2023-06-30", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/README.md#16-totalsupply-doesnt-represent-the-actual-token-supply", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/Vibe%20Security%20Audit%20Report.pdf" + }, + { + "title": "`require` checks without messages", + "content": "##### Description\nThere are a few `require` checks without corresponding messages - https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/RoyaltyReceiver.sol#L21, https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/RoyaltyReceiver.sol#L32, https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/RoyaltyReceiver.sol#L42, https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/RoyaltyReceiver.sol#L49, https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/tokens/VibeERC721.sol#L59, https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/tokens/VibeERC721.sol#L79, https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/tokens/VibeERC721.sol#L187, https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/tokens/VibeERC721.sol#L200, https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/mint/MintSaleBase.sol#L67, https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/mint/MintSaleBase.sol#L125, https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/mint/NFTMintSale.sol#L59, https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/mint/NFTMintSaleMultiple.sol#L75.\n\n##### Recommendation\nWe recommend adding necessary messages to the mentioned checks.\n\n***\n", + "protocol": "Vibe", + "report_date": "2023-06-30", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/README.md#17-require-checks-without-messages", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/Vibe%20Security%20Audit%20Report.pdf" + }, + { + "title": "The current minter status is not checked", + "content": "##### Description\nStatus can be changed to the same one here https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/tokens/VibeERC721.sol#L64.\n\n##### Recommendation\nWe recommend adding a check that the new status differs from the previous one.\n\n***\n", + "protocol": "Vibe", + "report_date": "2023-06-30", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/README.md#18-the-current-minter-status-is-not-checked", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/Vibe%20Security%20Audit%20Report.pdf" + }, + { + "title": "`claimed` can be updated for non-existing tiers", + "content": "##### Description\nIt is possible to update `claimed` mapping for non-existing tiers https://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/mint/NFTMintSaleWhitelistingMultiple.sol#L56\n\n##### Recommendation\nWe recommend adding a check that the `claimed` mapping cannot be updated for non-existing tiers.\n", + "protocol": "Vibe", + "report_date": "2023-06-30", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/README.md#19-claimed-can-be-updated-for-non-existing-tiers", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/Vibe%20Security%20Audit%20Report.pdf" + }, + { + "title": "Fees are not distributed at the beginning of `RoyaltyReceiver.setRecipientsAndBPS()`", + "content": "##### Description\nIf `RoyaltyReceiver.setRecipientsAndBPS()` is called, collected to that moment royalties are not distributed between old recipients. So, old royalties will be collected by new recipients.\n\n##### Recommendation\nWe recommend distributing already collected royalties at the beginning of `RoyaltyReceiver.setRecipientsAndBPS()`.\n", + "protocol": "Vibe", + "report_date": "2023-06-30", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/README.md#20-fees-are-not-distributed-at-the-beginning-of-royaltyreceiversetrecipientsandbps", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/Vibe%20Security%20Audit%20Report.pdf" + }, + { + "title": "NFT-owner can run minting again after `MintSaleBase.removeTokensAndReclaimOwnership()` was called", + "content": "##### Description\nAfter `MintSaleBase.removeTokensAndReclaimOwnership()` was called by NFT-owner, they can make a minting contract minter again with `VibeERC721.setMinter()`:\nhttps://github.com/vibexyz/vibe-contract/blob/d08057edbaf83b00d94dcaca2a05e3c44a45e4d9/contracts/tokens/VibeERC721.sol#L63\nSo, multiple `SaleEnded` or `SaleEndedEarly` events can be emitted for the same minting. If these events are used somewhere, it can lead to problems.\n\n##### Recommendation\nWe recommend adding some flags so that the minting is finished.\n", + "protocol": "Vibe", + "report_date": "2023-06-30", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/README.md#21-nft-owner-can-run-minting-again-after-mintsalebaseremovetokensandreclaimownership-was-called", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Vibe/Vibe%20Security%20Audit%20Report.pdf" + }, + { + "title": "Withdrawal of tokens from AMM", + "content": "##### Description\n\n`Controller` allows to call `AMM` via callback:\n\n```\nwithdraw_sig = get_method_id(\"withdraw(address,uint256)\") # AMM\n\ncontroller.liquidate_extended(user, 0, frac, True, \n market_amm.address, withdraw_sig, [])\n```\n\nhttps://github.com/curvefi/curve-stablecoin/blob/0d9265cc2dbd221b0f27f880fac1c590e1f12d28/contracts/AMM.vy#L728\n\n```\ndef withdraw(user: address, frac: uint256) -> uint256[2]:\n```\n\nThis method is sufficient to fulfill all the necessary conditions for a callback (https://github.com/curvefi/curve-stablecoin/blob/0d9265cc2dbd221b0f27f880fac1c590e1f12d28/contracts/Controller.vy#L525).\n\nUsing `liquidate_extended`, a hacker has the ability to withdraw any amount from `AMM`. It is also possible to make a complete liquidation through a partial one.\n\nThe test script was handed over to the customer.\n\n##### Recommendation\n\nIt is recommended to use a specific signature for calling a callback.\n", + "protocol": "Curve Finance", + "report_date": "2023-06-05", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Curve%20Finance/Curve%20Stablecoin%20(crvUSD)/README.md#1-withdrawal-of-tokens-from-amm", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Curve%20Finance/Curve%20Stablecoin%20(crvUSD)/Curve%20Stablecoin%20(crvUSD)%20Security%20Audit%20Report.pdf" + }, + { + "title": "Inflation attack on empty ticks", + "content": "##### Description\n\nEach AMM tick represents an empty vault, where shares are issued for collateral. A hacker can manipulate a tick so that it contains just 1 wei share and any amount of collateral. For example, suppose the hacker initially inflates the tick so that it contains 1 wei share and 1 ETH. Next, the hacker sees a victim's transaction in the mempool, which is going to deposit 20 ETH into this tick. The hacker then needs to inflate the tick to contain 1 wei share and 10 ETH + 1 wei right before the victim's transaction.\n\nHow many shares will the victim receive in this tick? The victim receives 1 wei share due to a rounding error:\n```\n1 wei share * 20 ETH / (10 ETH + 1 wei) = 1 wei share\n```\n\nNow there are 2 wei shares in total in this tick, one for the victim and one for the hacker.\n\nThe hacker then self-liquidates and receives 50% of the ether from the entire tick, which is 15 ETH, even though they initially invested 10 ETH. The profit is +5 ETH.\n\n**How does the hacker inflate the collateral in the tick?**\n\nStep 1. Before the frontrunning, the hacker ensures that the tick contains 1 share and 100+ wei ETH. They can do it using the AMM fee, performing `exchange()` back and forth. This is a heavy operation, plus there may be fees if there are other positions before the hacker's ticks. Therefore, this must be done in advance. After that the hacker self-liquidates 99% of their position, leaving one share. If there are no other positions before the hacker, they only spend money on gas.\n\nStep 2. Next, the hacker attacks themselves using an inflation attack. To do this, they perform `create_loan()+repay()` 100 times from another account. Each pass inflates the collateral by 1.5 times.\n\nHow it works:\n\nSuppose the tick currently contains 1 wei share and 106 wei collateral. The hacker deposits (106 * 2 - 1) wei collateral into the tick. How many shares will be minted?\n```\n1 wei share * (106 * 2 - 1) / 106 = 1 wei share\n```\n\nOnly 1 wei share was minted due to a rounding error.\n\nNow the tick has 2 wei shares and approximately `106 * 3` wei collateral.\n\nWhat happens when the hacker performs a full repay? They get back approximately\n```\n106 * 3 / 2 wei\n```\n\nThe tick remains with approximately the same amount: 1 wei share and `106 * 3 / 2` wei collateral.\n\nIt can be seen that one pass of `create_loan()+repay()` does not change the number of shares but increases the collateral by 1.5 times. 100 rounds can inflate the collateral from 106 wei to 42 ETH.\n\nThe test script was handed over to the customer.\n\n##### Recommendation\n\nThere are different approaches on how to solve the Inflation Attack problem. Some of the approaches along with their pros and cons, can be found in the OpenZeppelin github issue: https://github.com/OpenZeppelin/openzeppelin-contracts/issues/3706.\n\nOne way to resolve the problem is to use virtual dead shares, as implemented in the latest OpenZeppelin ERC-4626 vault:\n* https://github.com/OpenZeppelin/openzeppelin-contracts/blob/51294b7480fd13e716207a621ac1d55a6290d56d/contracts/token/ERC20/extensions/ERC4626.sol#L200\n* https://github.com/OpenZeppelin/openzeppelin-contracts/blob/51294b7480fd13e716207a621ac1d55a6290d56d/contracts/token/ERC20/extensions/ERC4626.sol#L207\n\nIn case this particular fix is chosen, it is recommended to use a virtual offset of 1000 ([which is the same number used in Uniswap V2](https://github.com/Uniswap/v2-core/blob/ee547b17853e71ed4e0101ccfd52e70d5acded58/contracts/UniswapV2Pair.sol#L120)), as this will make the residual possibility of griefing practically unattainable.\n", + "protocol": "Curve Finance", + "report_date": "2023-06-05", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Curve%20Finance/Curve%20Stablecoin%20(crvUSD)/README.md#2-inflation-attack-on-empty-ticks", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Curve%20Finance/Curve%20Stablecoin%20(crvUSD)/Curve%20Stablecoin%20(crvUSD)%20Security%20Audit%20Report.pdf" + }, + { + "title": "Withdrawal of tokens with debt as zero", + "content": "##### Description\n\nThis code allows you not to spend debt in liquidation (\nhttps://github.com/curvefi/curve-stablecoin/blob/0d9265cc2dbd221b0f27f880fac1c590e1f12d28/contracts/Controller.vy#L990):\n```\ndebt = unsafe_div(debt * frac, 10**18)\n```\n\nIf `debt * frac` is less than 10**18, then you don't have to pay for the liquidation part. We especially have the ability to eliminate the entire collateral by passing frac as 1. Example:\n\n```\nl_amount = 1\n\ncollateral_token._mint_for_testing(user, c_amount)\nmarket_controller.create_loan(c_amount, l_amount, n)\nmarket_controller.liquidate_extended(user, 0, 10 ** 18 - 1, \n True, ZERO_ADDRESS, [])\n# d_debt = 0\n# xy[0] = 0\n# xy[1] 1000\n# PROFIT stablecoin.balanceOf(user) +0\n# PROFIT collateral_token.balanceOf(user) +1000\n```\n\nIn this case, the attack is disadvantageous due to the gas.\n\n##### Recommendation\n\nIt is recommended to add an additional check that `debt != 0`.\n", + "protocol": "Curve Finance", + "report_date": "2023-06-05", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Curve%20Finance/Curve%20Stablecoin%20(crvUSD)/README.md#1-withdrawal-of-tokens-with-debt-as-zero", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Curve%20Finance/Curve%20Stablecoin%20(crvUSD)/Curve%20Stablecoin%20(crvUSD)%20Security%20Audit%20Report.pdf" + }, + { + "title": "`AMM.exchange()` produces negative fees", + "content": "##### Description\n\nUsing `exchange()` back-and-forth can generate profit without losing stablecoins. This occurs due to inaccuracies in calculating the invariant when AMM fees are low.\n\nThe profit generated from each tick is small (approximately 0.000000000136353050%), but under certain circumstances it can be significant enough for a hacker to execute an attack.\n\nFor example, let's assume that there are 100 billion USD spread across 1000 ticks and both the AMM fee and AMM admin fee are equal to zero. In this case, during a single back-and-forth pass, the hacker would earn 0.000000000136353050% from each tick and their total profit from the 100 billion would be approximately 0.136 USD.\n\nIf we consider that such a back-and-forth pass would take 833,333 gas, then at the current gas prices on the Ethereum mainnet, such an attack would not be economically feasible.\n\nHowever, the attack may become more relevant in the future if it is executed on a sidechain with low gas fees. For example, at a gas price of 130 gwei on the Polygon MATIC network (1 MATIC = $0.93), the hacker would spend approximately $0.10 on the attack but earn $0.136. The hacker can repeat the back-and-forth passes in a cycle within a single transaction 1000 times in a cycle and will get a net profit of $36 from a single transaction. By repeating this attack over and over again, they would be able to drain a significant portion of the funds available in the AMM.\n\nThe attack works with an AMM fee ranging from 0 to 650,000. Starting from an AMM fee of 1,000,000, the attack fails.\n\n##### Recommendation\n\nIt is recommended to set a limit on the minimum possible AMM fee of no less than 1,000,000.\n", + "protocol": "Curve Finance", + "report_date": "2023-06-05", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Curve%20Finance/Curve%20Stablecoin%20(crvUSD)/README.md#2-ammexchange-produces-negative-fees", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Curve%20Finance/Curve%20Stablecoin%20(crvUSD)/Curve%20Stablecoin%20(crvUSD)%20Security%20Audit%20Report.pdf" + }, + { + "title": "Raw calls on ETH transfers allow reentrancy", + "content": "##### Description\n\nIf WETH is used as collateral, users can choose to receive native ETH when it is sent to users. It happens in function `_withdraw_collateral()`.\n\n- https://github.com/curvefi/curve-stablecoin/blob/0d9265cc2dbd221b0f27f880fac1c590e1f12d28/contracts/Controller.vy#L514-L521\n\nIt breaks Checks-Effects-Interactions pattern. So, a call to an arbitrary address can be made in the middle of functions `repay()` and `_liquidate()`.\n\n- https://github.com/curvefi/curve-stablecoin/blob/0d9265cc2dbd221b0f27f880fac1c590e1f12d28/contracts/Controller.vy#L731\n- https://github.com/curvefi/curve-stablecoin/blob/0d9265cc2dbd221b0f27f880fac1c590e1f12d28/contracts/Controller.vy#L795\n- https://github.com/curvefi/curve-stablecoin/blob/0d9265cc2dbd221b0f27f880fac1c590e1f12d28/contracts/Controller.vy#L1054\n- https://github.com/curvefi/curve-stablecoin/blob/0d9265cc2dbd221b0f27f880fac1c590e1f12d28/contracts/Controller.vy#L1069\n\nThus, an attacker can reenter some other smart contract (excluding this Controller). For example, this attacker can call`rate_write()` in `AggMonetaryPolicy`, and the rate will be updated using old `total_debt` (not affected by ongoing `repay` or `liquidate`).\n\n##### Recommendation\n\nWe recommend limiting gas on native ETH transfers.\n\n\n", + "protocol": "Curve Finance", + "report_date": "2023-06-05", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Curve%20Finance/Curve%20Stablecoin%20(crvUSD)/README.md#1-raw-calls-on-eth-transfers-allow-reentrancy", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Curve%20Finance/Curve%20Stablecoin%20(crvUSD)/Curve%20Stablecoin%20(crvUSD)%20Security%20Audit%20Report.pdf" + }, + { + "title": "Not formalized stablecoin minting to addresses", + "content": "##### Description\n\nAdmin of `ControllerFactory` can mint any amount of stablecoin to any address calling `set_debt_ceiling`. It is designed to mint tokens to Controllers, but the function does not check that a receiver is among Controllers.\n- https://github.com/curvefi/curve-stablecoin/blob/0d9265cc2dbd221b0f27f880fac1c590e1f12d28/contracts/ControllerFactory.vy#L306-L313\n\nMoreover, this function is used to mint tokens to PegKeepers, and there are no checks that a receiver is among PegKeepers. The whole process is not protected and requires strong admin attention.\n\n##### Recommendation\n\nWe recommend checking that the inputted address in `set_debt_ceiling` is allowed to receive mint stablecoins (is among either Controllers or PegKeepers).\n", + "protocol": "Curve Finance", + "report_date": "2023-06-05", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Curve%20Finance/Curve%20Stablecoin%20(crvUSD)/README.md#2-not-formalized-stablecoin-minting-to-addresses", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Curve%20Finance/Curve%20Stablecoin%20(crvUSD)/Curve%20Stablecoin%20(crvUSD)%20Security%20Audit%20Report.pdf" + }, + { + "title": "Early liquidations via `repay()` front-running", + "content": "##### Description\n\nIf a user's position is underwater, a partial `repay()` does not move the borrower's bands but merely reduces the `initial_debt`:\n```\nelse: # partial repay\n\nif ns[0] > active_band:\n # Not in liquidation - can move bands\n ...\n\nelse:\n # Underwater - cannot move band but can avoid a bad liquidation\n ... # do nothing\n\nself.loan[_for] = Loan({initial_debt: debt, rate_mul: rate_mul}) \n```\n\n- https://github.com/curvefi/curve-stablecoin/blob/0d9265cc2dbd221b0f27f880fac1c590e1f12d28/contracts/Controller.vy#L777-L781\n\nA hacker can sandwich the victim's transaction:\n1. The hacker uses `exchange()` to move the `active_band` forward so the user's position becomes underwater. \n2. Then the user performs a partial `repay()` which now will not move the user's bands.\n3. The hacker returns their funds (minus fee) using `exchange()` back.\n\nIn the above example, if the collateral price goes lower, the user's position will be subject to liquidation much earlier.\n\nCurrently, a user cannot protect themselves from such griefing. If the user calls `repay(0)` to move their bands according to the actual debt, nothing will happen:\n\n```\ndef repay(_d_debt: ...):\n...\nif _d_debt == 0:\n return\n```\n\n- https://github.com/curvefi/curve-stablecoin/blob/1471b4177ece58d3f8c897cd8084be6ea03f11e0/contracts/Controller.vy#L731\n\n##### Recommendation\n\nIt is recommended to allow the user to move their bands by calling `repay(0)`.\n", + "protocol": "Curve Finance", + "report_date": "2023-06-05", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Curve%20Finance/Curve%20Stablecoin%20(crvUSD)/README.md#3-early-liquidations-via-repay-front-running", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Curve%20Finance/Curve%20Stablecoin%20(crvUSD)/Curve%20Stablecoin%20(crvUSD)%20Security%20Audit%20Report.pdf" + }, + { + "title": "`AggregateStablePrice` can be manipulated", + "content": "##### Description\n\nIf there is not enough liquidity in the pools or there are no pools, then `10**18` is returned as the price in `AggregateStablePrice`.\n\n- https://github.com/curvefi/curve-stablecoin/blob/0d9265cc2dbd221b0f27f880fac1c590e1f12d28/contracts/price_oracles/AggregateStablePrice.vy#L151\n\n```\nif Dsum == 0:\n return 10**18\n```\n\nIt is supposed to be used to manipulate the price. At an early stage of the project, this can be significant.\n\n##### Recommendation\nWe recommend taking these conditions into account when deploying contracts.\n", + "protocol": "Curve Finance", + "report_date": "2023-06-05", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Curve%20Finance/Curve%20Stablecoin%20(crvUSD)/README.md#4-aggregatestableprice-can-be-manipulated", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Curve%20Finance/Curve%20Stablecoin%20(crvUSD)/Curve%20Stablecoin%20(crvUSD)%20Security%20Audit%20Report.pdf" + }, + { + "title": "No checks of the result of `AMM.withdraw`", + "content": "##### Description\n\nAfter `withdraw` there is no check that this method did not return any amount.\n\nhttps://github.com/curvefi/curve-stablecoin/blob/0d9265cc2dbd221b0f27f880fac1c590e1f12d28/contracts/Controller.vy#L770\n\nThere will be either emptiness or dust, but it is worth checking or providing for such a possibility in a comment.\n\n##### Recommendation\nIt is recommended that you further check `xy[0]`.\n\n\n", + "protocol": "Curve Finance", + "report_date": "2023-06-05", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Curve%20Finance/Curve%20Stablecoin%20(crvUSD)/README.md#1-no-checks-of-the-result-of-ammwithdraw", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Curve%20Finance/Curve%20Stablecoin%20(crvUSD)/Curve%20Stablecoin%20(crvUSD)%20Security%20Audit%20Report.pdf" + }, + { + "title": "`AMM.exchange()` has no deadline", + "content": "##### Description\n\nThe `AMM.exchange()` and `AMM.exchange_dy()` functions have slippage checks for output tokens; however, they do not have a deadline check for the transaction:\n\n```\ndef exchange(i, j, in_amount, min_amount, _for)\n...\ndef exchange_dy(i, j, out_amount, max_amount, _for)\n```\n\n- https://github.com/curvefi/curve-stablecoin/blob/0d9265cc2dbd221b0f27f880fac1c590e1f12d28/contracts/AMM.vy#L1284-L1312\n\nA realistic scenario is possible where, due to high gas prices, an `exchange()` transaction will remain in the mempool for a significant amount of time, and the prices in the AMM may change significantly. This would allow MEV-bots to steal the user's positive slippage (unrealized profit).\n\n##### Recommendation\n\nIt is recommended to add a `deadline` parameter in exchange functions.\n\n", + "protocol": "Curve Finance", + "report_date": "2023-06-05", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Curve%20Finance/Curve%20Stablecoin%20(crvUSD)/README.md#2-ammexchange-has-no-deadline", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Curve%20Finance/Curve%20Stablecoin%20(crvUSD)/Curve%20Stablecoin%20(crvUSD)%20Security%20Audit%20Report.pdf" + }, + { + "title": "Not compatible with rebase/deflationary/hookable tokens and tokens with fees", + "content": "##### Description\n\nSmart contracts do not check token balances, and it only works for normal tokens without unexpected balance behavior. In addition, tokens with additional hooks can open additional attack vectors.\n\n##### Recommendation\n\nThis design is acceptable and even has some security advantages - if the project does not have plans to have AMMs with such tokens.\n", + "protocol": "Curve Finance", + "report_date": "2023-06-05", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Curve%20Finance/Curve%20Stablecoin%20(crvUSD)/README.md#3-not-compatible-with-rebasedeflationaryhookable-tokens-and-tokens-with-fees", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Curve%20Finance/Curve%20Stablecoin%20(crvUSD)/Curve%20Stablecoin%20(crvUSD)%20Security%20Audit%20Report.pdf" + }, + { + "title": "Key functions do not have return values", + "content": "##### Description\n\nMany key functions do not have return values but they imply different behavior in case of non-revert.\n\n- https://github.com/curvefi/curve-stablecoin/blob/0d9265cc2dbd221b0f27f880fac1c590e1f12d28/contracts/Controller.vy#L586\n- https://github.com/curvefi/curve-stablecoin/blob/0d9265cc2dbd221b0f27f880fac1c590e1f12d28/contracts/Controller.vy#L600\n- https://github.com/curvefi/curve-stablecoin/blob/0d9265cc2dbd221b0f27f880fac1c590e1f12d28/contracts/Controller.vy#L671\n- https://github.com/curvefi/curve-stablecoin/blob/0d9265cc2dbd221b0f27f880fac1c590e1f12d28/contracts/Controller.vy#L685\n- https://github.com/curvefi/curve-stablecoin/blob/0d9265cc2dbd221b0f27f880fac1c590e1f12d28/contracts/Controller.vy#L700\n- https://github.com/curvefi/curve-stablecoin/blob/0d9265cc2dbd221b0f27f880fac1c590e1f12d28/contracts/Controller.vy#L731\n- https://github.com/curvefi/curve-stablecoin/blob/0d9265cc2dbd221b0f27f880fac1c590e1f12d28/contracts/Controller.vy#L795\n- https://github.com/curvefi/curve-stablecoin/blob/0d9265cc2dbd221b0f27f880fac1c590e1f12d28/contracts/Controller.vy#L1054\n- https://github.com/curvefi/curve-stablecoin/blob/0d9265cc2dbd221b0f27f880fac1c590e1f12d28/contracts/Controller.vy#L1069\n\nIt can add more complexity on integration with other smart contracts.\n\n##### Recommendation\n\nWe recommend returning key values that can explain the results of call executions.\n\n\n", + "protocol": "Curve Finance", + "report_date": "2023-06-05", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Curve%20Finance/Curve%20Stablecoin%20(crvUSD)/README.md#4-key-functions-do-not-have-return-values", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Curve%20Finance/Curve%20Stablecoin%20(crvUSD)/Curve%20Stablecoin%20(crvUSD)%20Security%20Audit%20Report.pdf" + }, + { + "title": "ControllerFactory has unnecessary calculation operations", + "content": "##### Description\n\n\nControllerFactory stores the number of collaterals as a unit starting from `2**128`.\n\n- https://github.com/curvefi/curve-stablecoin/blob/0d9265cc2dbd221b0f27f880fac1c590e1f12d28/contracts/ControllerFactory.vy#L215\n\nThen it reads the number by subtracting`2**128`.\n\n- https://github.com/curvefi/curve-stablecoin/blob/0d9265cc2dbd221b0f27f880fac1c590e1f12d28/contracts/ControllerFactory.vy#L249\n- https://github.com/curvefi/curve-stablecoin/blob/0d9265cc2dbd221b0f27f880fac1c590e1f12d28/contracts/ControllerFactory.vy#L260\n\nCalculations with `2**128` can likely be dropped.\n\n##### Recommendation\n\nWe recommend removing calculations with `2**128`.\n", + "protocol": "Curve Finance", + "report_date": "2023-06-05", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Curve%20Finance/Curve%20Stablecoin%20(crvUSD)/README.md#5-controllerfactory-has-unnecessary-calculation-operations", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Curve%20Finance/Curve%20Stablecoin%20(crvUSD)/Curve%20Stablecoin%20(crvUSD)%20Security%20Audit%20Report.pdf" + }, + { + "title": "ControllerFactory.set_admin() does not have two-step ownership transferring", + "content": "##### Description\n\nAdmin can transfer ownership to anyone, even if it is a wrong address or zero-value address.\n\n- https://github.com/curvefi/curve-stablecoin/blob/0d9265cc2dbd221b0f27f880fac1c590e1f12d28/contracts/ControllerFactory.vy#L281-L288\n\n##### Recommendation\n\nWe recommend following a two-step procedure of ownership transferring when a new owner has to accept ownership.\n", + "protocol": "Curve Finance", + "report_date": "2023-06-05", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Curve%20Finance/Curve%20Stablecoin%20(crvUSD)/README.md#6-controllerfactoryset_admin-does-not-have-two-step-ownership-transferring", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Curve%20Finance/Curve%20Stablecoin%20(crvUSD)/Curve%20Stablecoin%20(crvUSD)%20Security%20Audit%20Report.pdf" + }, + { + "title": "Incorrect usage of the parameter", + "content": "##### Description\nThere are not enough checks on the amount of liquidity that can be removed from the limit order in the `decreaseLimitOrder` function. `liquidity` can be greater than the available liquidity on the limit order and in this case tx will revert. https://github.com/cryptoalgebra/Algebra/blob/bddd6487c86e0d6afef39638159dc403a91ba433/src/periphery/contracts/LimitOrderManager.sol#L162\n##### Recommendation\nWe recommend decreasing `liquidity` to `cache.liquidityLast` if `liquidity > cache.liquidityLast`.\n\n\n\n", + "protocol": "Algebra Finance", + "report_date": "2023-05-25", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Periphery/README.md#1-incorrect-usage-of-the-parameter", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Periphery/Algebra%20Periphery%20Security%20Audit%20Report.pdf" + }, + { + "title": "The operator address is not reset after the position token transfer", + "content": "##### Description\nA NFT position owner can set token `operator` to use permit functionality - https://github.com/cryptoalgebra/Algebra/blob/bddd6487c86e0d6afef39638159dc403a91ba433/src/periphery/contracts/LimitOrderManager.sol#L275. The operator address is used at the line https://github.com/cryptoalgebra/Algebra/blob/bddd6487c86e0d6afef39638159dc403a91ba433/src/periphery/contracts/LimitOrderManager.sol#L270. The `getApproved` function is used in a ERC721 standard to get an address of the entity which is allowed to make transfers. The user may give a permit to desired `operator`, then sell/transfer the NFT token. A new owner may not know about the given permit - the token operator is still able to make transfers and burn/collect a limit order position on behalf of the new token owner.\n##### Recommendation\nWe recommend overriding the ERC721 `_transfer` functionality and resetting the `_limitPositions[tokenId]` value on transfer.\n\n\n\n", + "protocol": "Algebra Finance", + "report_date": "2023-05-25", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Periphery/README.md#2-the-operator-address-is-not-reset-after-the-position-token-transfer", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Periphery/Algebra%20Periphery%20Security%20Audit%20Report.pdf" + }, + { + "title": "An inverted price is used for overflow validation during the creation of new limit orders", + "content": "##### Description\nIn function `core.LimitOrderManagement.addOrRemoveLimitOrder` the price used to evaluate whether the parameter `amountToBuy` is prone to overflow or does not appear to be inverted:\nhttps://github.com/cryptoalgebra/Algebra/blob/bddd6487c86e0d6afef39638159dc403a91ba433/src/core/contracts/libraries/LimitOrderManagement.sol#L46-L48\n```solidity\nuint256 amountToBuy = (tick > currentTick)\n ? FullMath.mulDivRoundingUp(_amountToSell, Constants.Q144, priceX144)\n : FullMath.mulDivRoundingUp(_amountToSell, priceX144, Constants.Q144);\n```\nPrice is represented as the ratio `token1/token0`. In the specified expression, if `tick` is greater than `currentTick`, then the new limit order position will sell `token0` in exchange for `token1`. Accordingly, to calculate the `amountToBuy`, `_amountToSell` , it should be multiplied by `priceX144` instead of being divided.\n##### Recommendation\nWe recommend inverting the specified expression.\n\n\n\n", + "protocol": "Algebra Finance", + "report_date": "2023-05-25", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Periphery/README.md#3-an-inverted-price-is-used-for-overflow-validation-during-the-creation-of-new-limit-orders", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Periphery/Algebra%20Periphery%20Security%20Audit%20Report.pdf" + }, + { + "title": "Possible reverts with no message", + "content": "##### Description\nThere are some places in the contracts that have the `require` checks without a revert message:\nhttps://github.com/cryptoalgebra/Algebra/blob/bddd6487c86e0d6afef39638159dc403a91ba433/src/periphery/contracts/LimitOrderManager.sol#L207\nhttps://github.com/cryptoalgebra/Algebra/blob/bddd6487c86e0d6afef39638159dc403a91ba433/src/periphery/contracts/libraries/PoolAddress.sol#L30.\n##### Recommendation\nWe recommend adding a message to all `require` statements.\n\n\n\n", + "protocol": "Algebra Finance", + "report_date": "2023-05-25", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Periphery/README.md#1-possible-reverts-with-no-message", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Periphery/Algebra%20Periphery%20Security%20Audit%20Report.pdf" + }, + { + "title": "Callback verification can be made more secure", + "content": "##### Description\nThe current callback verification is safe enough, but to increase the security of the protocol we would recommend saving the address of the pool that is used in the `_createLimitOrder` function to the storage variable to check that callback is called by the specific pool.\nhttps://github.com/cryptoalgebra/Algebra/blob/bddd6487c86e0d6afef39638159dc403a91ba433/src/periphery/contracts/base/LimitOrderManagement.sol#L24\n##### Recommendation\nWe recommend increasing the security of the callback validation.", + "protocol": "Algebra Finance", + "report_date": "2023-05-25", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Periphery/README.md#2-callback-verification-can-be-made-more-secure", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Periphery/Algebra%20Periphery%20Security%20Audit%20Report.pdf" + }, + { + "title": "Contract `LimitOrderManagement` can be removed", + "content": "##### Description\nSome functions of `LimitOrderManager` are placed in `LimitOrderManagement`. This contract has only one inheritor. There is also another contract with name `LimitOrderManagement` in the core part of the project. It may lead to confusion. \n##### Recommendation\nWe recommend moving functions from `LimitOrderManagement` to `LimitOrderManager` and removing `LimitOrderManagement`.\n\n\n\n", + "protocol": "Algebra Finance", + "report_date": "2023-05-25", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Periphery/README.md#3-contract-limitordermanagement-can-be-removed", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Periphery/Algebra%20Periphery%20Security%20Audit%20Report.pdf" + }, + { + "title": "The `LimitOrderManagement._createLimitOrder()` duplicated pool address calculation", + "content": "##### Description\n`LimitOrderManagement._createLimitOrder()` is called only from `LimitOrderManager.addLimitOrder()`. But it recalculates the address of the pool that was already calculated in `LimitOrderManagement._createLimitOrder()`:\nhttps://github.com/cryptoalgebra/Algebra/blob/bddd6487c86e0d6afef39638159dc403a91ba433/src/periphery/contracts/LimitOrderManager.sol#L81\nhttps://github.com/cryptoalgebra/Algebra/blob/bddd6487c86e0d6afef39638159dc403a91ba433/src/periphery/contracts/base/LimitOrderManagement.sol#L39.\n##### Recommendation\nWe recommend using a pool address as a parameter.\n\n\n\n", + "protocol": "Algebra Finance", + "report_date": "2023-05-25", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Periphery/README.md#4-the-limitordermanagement_createlimitorder-duplicated-pool-address-calculation", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Periphery/Algebra%20Periphery%20Security%20Audit%20Report.pdf" + }, + { + "title": "Accidental calling of `LimitOrderManagement.collectLimitOrder()` with zero recipient may lead to tokens stealing", + "content": "##### Description\nIf `LimitOrderManagement.collectLimitOrder()` is called by accident for zero recipient, tokens will be transferred to the contract address:\nhttps://github.com/cryptoalgebra/Algebra/blob/bddd6487c86e0d6afef39638159dc403a91ba433/src/periphery/contracts/LimitOrderManager.sol#LL229C1-L229C1\nAfter that, anyone can claim them.\n##### Recommendation\nWe recommend reverting `LimitOrderManagement.collectLimitOrder()` if `recipient` is `address(0)`.", + "protocol": "Algebra Finance", + "report_date": "2023-05-25", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Periphery/README.md#5-accidental-calling-of-limitordermanagementcollectlimitorder-with-zero-recipient-may-lead-to-tokens-stealing", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Periphery/Algebra%20Periphery%20Security%20Audit%20Report.pdf" + }, + { + "title": "Gas optimization", + "content": "##### Description\nThere is a `_getAndIncrementNonce` function at the line https://github.com/cryptoalgebra/Algebra/blob/bddd6487c86e0d6afef39638159dc403a91ba433/src/periphery/contracts/LimitOrderManager.sol#L262. Its logic can be put into an `unchecked` block to skip overflow checks (like it is done here - https://github.com/cryptoalgebra/Algebra/blob/bddd6487c86e0d6afef39638159dc403a91ba433/src/periphery/contracts/NonfungiblePositionManager.sol#L480).\n##### Recommendation\nWe recommend putting the function code into the `unchecked` block.\n\n\n\n", + "protocol": "Algebra Finance", + "report_date": "2023-05-25", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Periphery/README.md#6-gas-optimization", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Periphery/Algebra%20Periphery%20Security%20Audit%20Report.pdf" + }, + { + "title": "The missing check for a recipient's address", + "content": "##### Description\nThere are two functions - https://github.com/cryptoalgebra/Algebra/blob/bddd6487c86e0d6afef39638159dc403a91ba433/src/periphery/contracts/base/PeripheryPayments.sol#L21 and https://github.com/cryptoalgebra/Algebra/blob/bddd6487c86e0d6afef39638159dc403a91ba433/src/periphery/contracts/base/PeripheryPayments.sol#L32 which accept the `recipient` address as a parameter. As the `recipient` parameter value is not checked, it is possible to transfer tokens to zero address.\n##### Recommendation\nWe recommend adding checks that the `recipient` is not a zero address in both functions.", + "protocol": "Algebra Finance", + "report_date": "2023-05-25", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Periphery/README.md#7-the-missing-check-for-a-recipients-address", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Periphery/Algebra%20Periphery%20Security%20Audit%20Report.pdf" + }, + { + "title": "An unnecessary subtraction operation", + "content": "##### Description\nAt the line https://github.com/cryptoalgebra/Algebra/blob/bddd6487c86e0d6afef39638159dc403a91ba433/src/periphery/contracts/LimitOrderManager.sol#L246 the `position.tokensOwed0` and `position.tokensOwed1` values are set to the result of subtraction of the previous `tokensOwed` value and the amount collected. But at line https://github.com/cryptoalgebra/Algebra/blob/bddd6487c86e0d6afef39638159dc403a91ba433/src/periphery/contracts/LimitOrderManager.sol#L239 the collected values are initialized with the owed values. It is unnecessary to do a subtraction when both operators have the same value.\n##### Recommendation\nWe recommend assigning zero values to `position.tokensOwed0` and `position.tokensOwed1` here - https://github.com/cryptoalgebra/Algebra/blob/bddd6487c86e0d6afef39638159dc403a91ba433/src/periphery/contracts/LimitOrderManager.sol#LL246C32-L246C52.\n\n\n\n", + "protocol": "Algebra Finance", + "report_date": "2023-05-25", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Periphery/README.md#8-an-unnecessary-subtraction-operation", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Periphery/Algebra%20Periphery%20Security%20Audit%20Report.pdf" + }, + { + "title": "`decreaseLimitOrder` can be called multiple times on an emptied order", + "content": "##### Description\nThere is a function https://github.com/cryptoalgebra/Algebra/blob/bddd6487c86e0d6afef39638159dc403a91ba433/src/periphery/contracts/LimitOrderManager.sol#L137 which is used to reduce a user's position (or fully close limit orders). When a user removes all liquidity from their position but not burns the NFT token, they are still able to call `decreaseLimitOrder` multiple times. \n##### Recommendation\nWe recommend adding a check for `position.liquidity` being greater than zero at the beginning of the `decreaseLimitOrder` function.\n\n\n\n", + "protocol": "Algebra Finance", + "report_date": "2023-05-25", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Periphery/README.md#9-decreaselimitorder-can-be-called-multiple-times-on-an-emptied-order", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Periphery/Algebra%20Periphery%20Security%20Audit%20Report.pdf" + }, + { + "title": "Unprotected `sweep` function", + "content": "##### Description\nCurrently, any user can call the sweep function and get all tokens from the contract.\nhttps://github.com/cryptoalgebra/Algebra/blob/bddd6487c86e0d6afef39638159dc403a91ba433/src/periphery/contracts/base/PeripheryPayments.sol#L32-L48\n##### Recommendation\nWe recommend adding an admin role for calling this function.", + "protocol": "Algebra Finance", + "report_date": "2023-05-25", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Periphery/README.md#10-unprotected-sweep-function", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Periphery/Algebra%20Periphery%20Security%20Audit%20Report.pdf" + }, + { + "title": "Code impossible to reach out", + "content": "##### Description\nThere is a branch in the `pay` function that cannot be reached:\nhttps://github.com/cryptoalgebra/Algebra/blob/bddd6487c86e0d6afef39638159dc403a91ba433/src/periphery/contracts/base/PeripheryPayments.sol#L64-L66.\n##### Recommendation\nWe recommend removing this branch from the contract.", + "protocol": "Algebra Finance", + "report_date": "2023-05-25", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Periphery/README.md#11-code-impossible-to-reach-out", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Periphery/Algebra%20Periphery%20Security%20Audit%20Report.pdf" + }, + { + "title": "Users' rewards can be lost if the incentive maker adds a new farming with the same key", + "content": "##### Description\nIf the incentive maker adds a new farming after the previous one was unattached by the pool, then all users' rewards will be lost.\nhttps://github.com/cryptoalgebra/Algebra/blob/7290fad656bfa89db3743c52af631154f6a8a2d5/src/tokenomics/contracts/farmings/AlgebraEternalFarming.sol#L113\nhttps://github.com/cryptoalgebra/Algebra/blob/7290fad656bfa89db3743c52af631154f6a8a2d5/src/tokenomics/contracts/farmings/AlgebraEternalFarming.sol#L303\n\n##### Recommendation\nWe recommend adding a check that the maker cannot create a farming with the same key.\n\n", + "protocol": "Algebra Finance", + "report_date": "2023-05-24", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/README.md#1-users-rewards-can-be-lost-if-the-incentive-maker-adds-a-new-farming-with-the-same-key", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/Algebra%20Farmings%20Security%20Audit%20Report.pdf" + }, + { + "title": "The reward distributor can send funds to an unattached pool", + "content": "##### Description\nThere is no check in the `addRewards()` function that would stop the reward distributor from sending funds to a virtual pool that was unattached from the Algebra pool due to a revert in the `crossTo()` function.\nhttps://github.com/cryptoalgebra/Algebra/blob/7290fad656bfa89db3743c52af631154f6a8a2d5/src/tokenomics/contracts/farmings/AlgebraEternalFarming.sol#L186-L195\n\n##### Recommendation\nWe recommend adding the following check:\n```solidity=\nIAlgebraEternalVirtualPool virtualPool = \n IAlgebraEternalVirtualPool(_getCurrentVirtualPool(key.pool));\nif (incentive.virtualPoolAddress != \n address(virtualPool)) revert anotherFarmingIsActive();\n```\n", + "protocol": "Algebra Finance", + "report_date": "2023-05-24", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/README.md#2-the-reward-distributor-can-send-funds-to-an-unattached-pool", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/Algebra%20Farmings%20Security%20Audit%20Report.pdf" + }, + { + "title": "The creation of the incentive with zero rewards blocks the pool's incentive system", + "content": "##### Description\nIt's possible to create an incentive with 0 rewards using `AlgebraEternalFarming.createEternalFarming()`:\nhttps://github.com/cryptoalgebra/Algebra/blob/7290fad656bfa89db3743c52af631154f6a8a2d5/src/tokenomics/contracts/farmings/AlgebraEternalFarming.sol#L103.\nLater `AlgebraEternalFarming._getIncentiveByKey()` will revert for such incentives:\nhttps://github.com/cryptoalgebra/Algebra/blob/7290fad656bfa89db3743c52af631154f6a8a2d5/src/tokenomics/contracts/farmings/AlgebraEternalFarming.sol#L418.\nSo, it will be impossible to call `AlgebraEternalFarming.deactivateIncentive()`, `AlgebraEternalFarming.decreaseRewardsAmount()`, or `AlgebraEternalFarming.addRewards()`. So, the pool will be blocked from the creation of any incentive. If there are some bonus rewards for this incentive, they will be stuck forever.\n##### Recommendation\nWe recommend adding a require clause for non-zero rewards in `AlgebraEternalFarming.createEternalFarming()`.\n", + "protocol": "Algebra Finance", + "report_date": "2023-05-24", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/README.md#3-the-creation-of-the-incentive-with-zero-rewards-blocks-the-pools-incentive-system", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/Algebra%20Farmings%20Security%20Audit%20Report.pdf" + }, + { + "title": "Unsynchronized positions in `NonFungiblePositionManager` and `AlgebraEternalFarming` can be exploited for receiving unfair rewards", + "content": "##### Description\n\nIf `FarmingCenter._updatePosition` reverts internally, `NonFungiblePositionManager` ignores that revert here: https://github.com/cryptoalgebra/Algebra/blob/7290fad656bfa89db3743c52af631154f6a8a2d5/src/periphery/contracts/NonfungiblePositionManager.sol#L369 leading to unsynchronized positions between the actual position and the farming position. The `_updatePosition` function consists of sequential calls to the `exitFarming` and `enterFarming` functions within the `AlgebraEternalFarming` contract https://github.com/cryptoalgebra/Algebra/blob/7290fad656bfa89db3743c52af631154f6a8a2d5/src/tokenomics/contracts/FarmingCenter.sol#L94. While the `exitFarming` function does not possess explicit revert statements, the `enterFarming` function can revert here: https://github.com/cryptoalgebra/Algebra/blob/7290fad656bfa89db3743c52af631154f6a8a2d5/src/tokenomics/contracts/farmings/AlgebraEternalFarming.sol#L385. These reverts prevent the creation of farming positions in detached or deactivated farmings. Consequently, if a pool is detached, every call to `NonFungiblePositionManager.decreaseLiquidity` will revert within the `FarmingCenter._updatePosition` function. As a result, the actual liquidity of the position in the pool will decrease, but the liquidity in the farming position will remain unchanged, allowing the `tokenId` owner to continue collecting higher rewards than deserved.\n\nFurthermore, this vulnerability can be exploited by users who can find a way to manually detach the pool from its incentive. Consider the following scenario:\n\n* The exploiter obtains a flashloan from an external project\n* The exploiter mints a position in the pool using loaned tokens and enters farming\n* The exploiter detaches the pool\n* The exploiter decreases liquidity of the position to the minimum possible causing desynchronization in `AlgebraEternalFarming` which retains the liquidity of the flahsloaned tokens.\n* The exploiter repays the flashloan\n\nIn this scenario, the exploiter can collect rewards without maintaining an actual position.\n\n##### Recommendation\nWe recommend implementing the forced exit from the farming position in cases when a revert occurs within the call of `NonFungiblePositionManager` here: https://github.com/cryptoalgebra/Algebra/blob/7290fad656bfa89db3743c52af631154f6a8a2d5/src/periphery/contracts/NonfungiblePositionManager.sol#L369, if feasible, to prevent unsynchronized farming positions.\n", + "protocol": "Algebra Finance", + "report_date": "2023-05-24", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/README.md#4-unsynchronized-positions-in-nonfungiblepositionmanager-and-algebraeternalfarming-can-be-exploited-for-receiving-unfair-rewards", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/Algebra%20Farmings%20Security%20Audit%20Report.pdf" + }, + { + "title": "Virtual pools detached from the corresponding `AlgebraPool` result in an inconsistent state", + "content": "##### Description\nIn cases where `AlgebraPool` connected to `VirtualAlgebraPool` catches a revert during a call to the `crossTo` function, the pool will reset its `activeIncentive` parameter to the 0 address here: https://github.com/cryptoalgebra/Algebra/blob/7290fad656bfa89db3743c52af631154f6a8a2d5/src/core/contracts/base/SwapCalculation.sol#L210.\nSubsequently, the virtual pool enters a state where it is not `deactivated`, its `rewardRates` remain non-zero, and the detached pool no longer updates subsequent price changes. As a result, current liquidity providers continue to collect rewards based on the \"frozen\" price present in the pool at the moment of detachment.\n\n##### Recommendation\nWe recommend updating `rewardRates` for the pool to 0 and setting the `deactivated` state to `true` during the detachment process to prevent the accumulation of rewards based on outdated prices.\n", + "protocol": "Algebra Finance", + "report_date": "2023-05-24", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/README.md#5-virtual-pools-detached-from-the-corresponding-algebrapool-result-in-an-inconsistent-state", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/Algebra%20Farmings%20Security%20Audit%20Report.pdf" + }, + { + "title": "An incorrect sequence of calls can lead to a revert", + "content": "##### Description\nGetting reserves before applying new rewards can lead to a revert on a call of the `decreaseRewardsAmount()` function.\nhttps://github.com/cryptoalgebra/Algebra/blob/7290fad656bfa89db3743c52af631154f6a8a2d5/src/tokenomics/contracts/farmings/AlgebraEternalFarming.sol#L161\n\n##### Recommendation\nWe recommend calling `distributeRewards()` before getting reserves of the farming.\n", + "protocol": "Algebra Finance", + "report_date": "2023-05-24", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/README.md#1-an-incorrect-sequence-of-calls-can-lead-to-a-revert", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/Algebra%20Farmings%20Security%20Audit%20Report.pdf" + }, + { + "title": "Rates can be updated for a deactivated farming", + "content": "##### Description\nThere is no check that the incentive maker can't set non-zero rates for a deactivated pool.\nhttps://github.com/cryptoalgebra/Algebra/blob/7290fad656bfa89db3743c52af631154f6a8a2d5/src/tokenomics/contracts/farmings/AlgebraEternalFarming.sol#L198-L202\n\n##### Recommendation\nWe recommend adding a check that the farming was deactivated and this case allows setting only zero rates.\n", + "protocol": "Algebra Finance", + "report_date": "2023-05-24", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/README.md#2-rates-can-be-updated-for-a-deactivated-farming", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/Algebra%20Farmings%20Security%20Audit%20Report.pdf" + }, + { + "title": "Initialization of the `virtualPool` should be made earlier", + "content": "##### Description\n`virtualPool` is currently initialized after using it in the check.\nhttps://github.com/cryptoalgebra/Algebra/blob/7290fad656bfa89db3743c52af631154f6a8a2d5/src/tokenomics/contracts/farmings/AlgebraEternalFarming.sol#L398\n\n##### Recommendation\nWe recommend initializing `virtualPool` at the beginning of the function.\n", + "protocol": "Algebra Finance", + "report_date": "2023-05-24", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/README.md#3-initialization-of-the-virtualpool-should-be-made-earlier", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/Algebra%20Farmings%20Security%20Audit%20Report.pdf" + }, + { + "title": "Admin can drain all rewards from all incentives", + "content": "##### Description\n\n`AlgebraEternalFarming.decreaseRewardsAmount()` sends rewards to the address of admin:\nhttps://github.com/cryptoalgebra/Algebra/blob/7290fad656bfa89db3743c52af631154f6a8a2d5/src/tokenomics/contracts/farmings/AlgebraEternalFarming.sol#L172.\nIt creates the danger of a rugpull and reduces the trust in the incentive system.\n\n##### Recommendation\nWe recommend changing the logic of rewards refunds. An incentive for specific farming should be controlled by a registered address for this incentive.\n", + "protocol": "Algebra Finance", + "report_date": "2023-05-24", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/README.md#4-admin-can-drain-all-rewards-from-all-incentives", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/Algebra%20Farmings%20Security%20Audit%20Report.pdf" + }, + { + "title": "Unused variables", + "content": "##### Description\nSeveral storage variables can be removed:\nhttps://github.com/cryptoalgebra/Algebra/blob/7290fad656bfa89db3743c52af631154f6a8a2d5/src/tokenomics/contracts/FarmingCenter.sol#L21\nhttps://github.com/cryptoalgebra/Algebra/blob/7290fad656bfa89db3743c52af631154f6a8a2d5/src/tokenomics/contracts/libraries/VirtualTickManagement.sol#L23\nhttps://github.com/cryptoalgebra/Algebra/blob/7290fad656bfa89db3743c52af631154f6a8a2d5/src/tokenomics/contracts/farmings/EternalVirtualPool.sol#L18.\n\n##### Recommendation\nWe recommend removing these variables from storage.\n", + "protocol": "Algebra Finance", + "report_date": "2023-05-24", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/README.md#1-unused-variables", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/Algebra%20Farmings%20Security%20Audit%20Report.pdf" + }, + { + "title": "Events missing", + "content": "##### Description\nSeveral functions should emit an event for better UX in possible integrations:\nhttps://github.com/cryptoalgebra/Algebra/blob/7290fad656bfa89db3743c52af631154f6a8a2d5/src/tokenomics/contracts/farmings/AlgebraEternalFarming.sol#L186-L195\nhttps://github.com/cryptoalgebra/Algebra/blob/7290fad656bfa89db3743c52af631154f6a8a2d5/src/tokenomics/contracts/farmings/AlgebraEternalFarming.sol#L198-L202.\n\n##### Recommendation\nWe recommend emitting events after these function calls.\n", + "protocol": "Algebra Finance", + "report_date": "2023-05-24", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/README.md#2-events-missing", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/Algebra%20Farmings%20Security%20Audit%20Report.pdf" + }, + { + "title": "Unchecked calculations can be dangerous in some places", + "content": "##### Description\nThere are several places where it is better to not use unchecked calculations:\nhttps://github.com/cryptoalgebra/Algebra/blob/7290fad656bfa89db3743c52af631154f6a8a2d5/src/tokenomics/contracts/farmings/AlgebraEternalFarming.sol#L327-L332\nhttps://github.com/cryptoalgebra/Algebra/blob/7290fad656bfa89db3743c52af631154f6a8a2d5/src/tokenomics/contracts/farmings/AlgebraEternalFarming.sol#L160-L168.\n\n##### Recommendation\nWe recommend not using unchecked calculations in these places.\n", + "protocol": "Algebra Finance", + "report_date": "2023-05-24", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/README.md#3-unchecked-calculations-can-be-dangerous-in-some-places", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/Algebra%20Farmings%20Security%20Audit%20Report.pdf" + }, + { + "title": "If a user transfers NFT, they can lose rewards", + "content": "##### Description\nIf the user transfer NFT before calling `collectRewards`, they will lose accrued rewards\nhttps://github.com/cryptoalgebra/Algebra/blob/7290fad656bfa89db3743c52af631154f6a8a2d5/src/tokenomics/contracts/FarmingCenter.sol#L113-L115.\n\n##### Recommendation\nWe recommend adding a check to the transfer function that rewards were collected before the transfer.\n", + "protocol": "Algebra Finance", + "report_date": "2023-05-24", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/README.md#4-if-a-user-transfers-nft-they-can-lose-rewards", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/Algebra%20Farmings%20Security%20Audit%20Report.pdf" + }, + { + "title": "`EternalVirtualPool._distributeRewards()` has an unnecessary parameter", + "content": "##### Description\nInternal function `EternalVirtualPool._distributeRewards()` uses the `currentTimestamp` parameter:\nhttps://github.com/cryptoalgebra/Algebra/blob/7290fad656bfa89db3743c52af631154f6a8a2d5/src/tokenomics/contracts/farmings/EternalVirtualPool.sol#L208.\n\n##### Recommendation\nWe recommend using `uint32(block.timestamp)` directly in the function.\n", + "protocol": "Algebra Finance", + "report_date": "2023-05-24", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/README.md#5-eternalvirtualpool_distributerewards-has-an-unnecessary-parameter", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/Algebra%20Farmings%20Security%20Audit%20Report.pdf" + }, + { + "title": "An unnecessary allowed caller in `EternalVirtualPool.crossTo()`", + "content": "##### Description\n`EternalVirtualPool.crossTo()` is allowed to be called by `farmingCenterAddress` but it's never called from the farming center:\nhttps://github.com/cryptoalgebra/Algebra/blob/7290fad656bfa89db3743c52af631154f6a8a2d5/src/tokenomics/contracts/farmings/EternalVirtualPool.sol#L103.\n\n##### Recommendation\nWe recommend removing `farmingCenterAddress` from allowed callers.\n", + "protocol": "Algebra Finance", + "report_date": "2023-05-24", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/README.md#6-an-unnecessary-allowed-caller-in-eternalvirtualpoolcrossto", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/Algebra%20Farmings%20Security%20Audit%20Report.pdf" + }, + { + "title": "An unnecessary incentive storage change", + "content": "##### Description\n`AlgebraEternalFarming._enterFarming()` marks the incentive as deactivated in the storage and after that reverts in case of the virtual pool address desynchronization:\nhttps://github.com/cryptoalgebra/Algebra/blob/7290fad656bfa89db3743c52af631154f6a8a2d5/src/tokenomics/contracts/farmings/AlgebraEternalFarming.sol#L386.\nBut the storage changes are not saved in case of a revert.\n\n##### Recommendation\nWe recommend reverting without storage changes.\n", + "protocol": "Algebra Finance", + "report_date": "2023-05-24", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/README.md#7-an-unnecessary-incentive-storage-change", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/Algebra%20Farmings%20Security%20Audit%20Report.pdf" + }, + { + "title": "`INCENTIVE_MAKER` can create an incentive for any IAlgebraPool", + "content": "##### Description\n`INCENTIVE_MAKER` can create an incentive for any `IAlgebraPool`, not only for the ones created by the factory:\nhttps://github.com/cryptoalgebra/Algebra/blob/7290fad656bfa89db3743c52af631154f6a8a2d5/src/tokenomics/contracts/farmings/AlgebraEternalFarming.sol#L103.\nIt can be used in some complicated attacks by `INCENTIVE_MAKER`. \n\n##### Recommendation\nWe recommend checking the pool address if it's created by the factory.\n", + "protocol": "Algebra Finance", + "report_date": "2023-05-24", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/README.md#8-incentive_maker-can-create-an-incentive-for-any-ialgebrapool", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/Algebra%20Farmings%20Security%20Audit%20Report.pdf" + }, + { + "title": "Anyone can call `AlgebraEternalFarming.addRewards()`", + "content": "##### Description\n`AlgebraEternalFarming.addRewards()` can be called by any address:\nhttps://github.com/cryptoalgebra/Algebra/blob/7290fad656bfa89db3743c52af631154f6a8a2d5/src/tokenomics/contracts/farmings/AlgebraEternalFarming.sol#L186.\nSo, anyone can manipulate the size of the total rewards. It can be used in some complicated attacks.\n\n##### Recommendation\nWe recommend implementing a whitelist for addresses that can add rewards.\n", + "protocol": "Algebra Finance", + "report_date": "2023-05-24", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/README.md#9-anyone-can-call-algebraeternalfarmingaddrewards", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/Algebra%20Farmings%20Security%20Audit%20Report.pdf" + }, + { + "title": "An incorrect (misspelled) word in the comment", + "content": "##### Description\nAt line https://github.com/cryptoalgebra/Algebra/blob/7290fad656bfa89db3743c52af631154f6a8a2d5/src/tokenomics/contracts/libraries/VirtualTickManagement.sol#L134 a misspelled word is used. \n\n##### Recommendation\nWe recommend changing `if` to `of`.\n", + "protocol": "Algebra Finance", + "report_date": "2023-05-24", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/README.md#10-an-incorrect-misspelled-word-in-the-comment", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/Algebra%20Farmings%20Security%20Audit%20Report.pdf" + }, + { + "title": "An unnecessary type cast", + "content": "##### Description\nAt line https://github.com/cryptoalgebra/Algebra/blob/7290fad656bfa89db3743c52af631154f6a8a2d5/src/tokenomics/contracts/farmings/AlgebraEternalFarming.sol#L99 variable `factory` is cast to the `IAlgebraFactory` type, but it already has the `IAlgebraFactory` type by definition - https://github.com/cryptoalgebra/Algebra/blob/7290fad656bfa89db3743c52af631154f6a8a2d5/src/tokenomics/contracts/farmings/AlgebraEternalFarming.sol#L52.\n\n##### Recommendation\nWe recommend removing unnecessary cast operations.\n", + "protocol": "Algebra Finance", + "report_date": "2023-05-24", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/README.md#11-an-unnecessary-type-cast", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/Algebra%20Farmings%20Security%20Audit%20Report.pdf" + }, + { + "title": "The detached `Incentive` cannot be deactivated manually", + "content": "##### Description\nIf the virtual pool is detached from its corresponding algebra pool, then it is impossible for the incentive manager to manually change its status to the `deactivated` state due to this check: https://github.com/cryptoalgebra/Algebra/blob/7290fad656bfa89db3743c52af631154f6a8a2d5/src/tokenomics/contracts/farmings/AlgebraEternalFarming.sol#L143.\n\n##### Recommendation\nWe recommend modifying the specified expression to \n```solidity\nif (incentive.virtualPoolAddress == address(0)) ...\n```\n", + "protocol": "Algebra Finance", + "report_date": "2023-05-24", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/README.md#12-the-detached-incentive-cannot-be-deactivated-manually", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/Algebra%20Farmings%20Security%20Audit%20Report.pdf" + }, + { + "title": "A redundant call to `_updatePositionInVirtualPool` in the `_updatePosition` function", + "content": "##### Description\nThe call to `_updatePositionInVirtualPool` here \nhttps://github.com/cryptoalgebra/Algebra/blob/7290fad656bfa89db3743c52af631154f6a8a2d5/src/tokenomics/contracts/farmings/AlgebraEternalFarming.sol#L263 can be replaced with the `distributeRewards` call since the`liquidityDelta` argument is set to 0 at that point.\n\n##### Recommendation\nWe recommend changing the `_updatePositionInVirtualPool` call in the specified line to `virtualPool.distributeRewards()`.\n", + "protocol": "Algebra Finance", + "report_date": "2023-05-24", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/README.md#13-a-redundant-call-to-_updatepositioninvirtualpool-in-the-_updateposition-function", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/Algebra%20Farmings%20Security%20Audit%20Report.pdf" + }, + { + "title": "`getInnerRewardsGrowth` can be called for non-existed ticks", + "content": "##### Description\nThere are no checks in the `getInnerRewardsGrowth` function that `bottomTick` and `topTick` were added to the tick tree.\nhttps://github.com/cryptoalgebra/Algebra/blob/7290fad656bfa89db3743c52af631154f6a8a2d5/src/tokenomics/contracts/farmings/EternalVirtualPool.sol#L64-L67\n\n##### Recommendation\nWe recommend adding checks that ticks were added to restrict external calls with incorrect input parameters.\n", + "protocol": "Algebra Finance", + "report_date": "2023-05-24", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/README.md#14-getinnerrewardsgrowth-can-be-called-for-non-existed-ticks", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/Algebra%20Farmings%20Security%20Audit%20Report.pdf" + }, + { + "title": "The check can be made earlier to save gas", + "content": "##### Description\nThe liquidity of the position check can be made earlier to save some gas.\nhttps://github.com/cryptoalgebra/Algebra/blob/7290fad656bfa89db3743c52af631154f6a8a2d5/src/tokenomics/contracts/farmings/AlgebraEternalFarming.sol#L209\n\n##### Recommendation\nWe recommend checking the liquidity of the position before calling `_enterFarming()`.\n", + "protocol": "Algebra Finance", + "report_date": "2023-05-24", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/README.md#15-the-check-can-be-made-earlier-to-save-gas", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/Algebra%20Farmings%20Security%20Audit%20Report.pdf" + }, + { + "title": "Rebasable tokens cannot be used for rewards", + "content": "##### Description\nThe current farming design doesn't allow work with rebasable tokens.\n\n##### Recommendation\nWe recommend restricting work with rebasable tokens. This information can be added to the protocol documentation.\n", + "protocol": "Algebra Finance", + "report_date": "2023-05-24", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/README.md#16-rebasable-tokens-cannot-be-used-for-rewards", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/Algebra%20Farmings%20Security%20Audit%20Report.pdf" + }, + { + "title": "Zero checks are missing", + "content": "##### Description\nThe protocol allows to transfer 0 amount of tokens to the 0 address.\nhttps://github.com/cryptoalgebra/Algebra/blob/7290fad656bfa89db3743c52af631154f6a8a2d5/src/tokenomics/contracts/farmings/AlgebraEternalFarming.sol#L410\n\n##### Recommendation\nWe recommend adding a check that tokens cannot be transferred to the 0 address and farming doesn't try to send 0 tokens.\n", + "protocol": "Algebra Finance", + "report_date": "2023-05-24", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/README.md#17-zero-checks-are-missing", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Algebra%20Finance/Farmings/Algebra%20Farmings%20Security%20Audit%20Report.pdf" + }, + { + "title": "An incorrect version calculation will lead to a token loss for a user", + "content": "##### Description\nA token version is calculated incorrectly (the version is in range [10_000:990_000]) which means that a user will lose a token from the current collection and receive a token from another collection (which probably hasn't existed yet).\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/utils/TokenVersionUtil.sol#L23-L24\n\n##### Recommendation\nWe recommend changing the calculation of the token version logic in the `getTokenInfo()` function in the `TokenVersionUtil` library.\n\n\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#1-an-incorrect-version-calculation-will-lead-to-a-token-loss-for-a-user", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "There are no checks that an athlete sent funds to the FantiumClaimingV1 contract", + "content": "##### Description\nThere are no checks that an athlete has sent tokens to the contract (`amountPaidIn` is not checked). So, users from the collections that are not able to claim funds will be able to claim them from other distributions. It can be extremely dangerous if some of the athletes do not send funds to the contract on time.\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L405\n\n##### Recommendation\nWe recommend adding a simple check: `require(distributionEvents[_distributionEventId].amountPaidIn, \"Unable to claim\");`.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#2-there-are-no-checks-that-an-athlete-sent-funds-to-the-fantiumclaimingv1-contract", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "An unlimited claim", + "content": "##### Description\nAn unnecessary check was implemented instead of updating the mapping here:\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L456-L458 \nThis allows an unlimited claim for a user, so anybody with an NFT could drain the contract.\n\n##### Recommendation\nWe recommend adding a change from `==` to `=`.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#3-an-unlimited-claim", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "A possible transfer of funds of another athlete", + "content": "##### Description\nThere is no check that an athlete has already transferred funds to the contract here: https://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L624-L652 \nIt means that the manager by mistake can transfer the funds of another athlete to the athlete that asked to close their distribution.\n\n##### Recommendation\nWe recommend adding a simple check: `require(distributionEvents[_distributionEventId].amountPaidIn, \"Unable to close\");`.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#4-a-possible-transfer-of-funds-of-another-athlete", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Some distribution parameters cannot be updated after funds sending", + "content": "##### Description\nThe updating of `tournamentDistributionAmount`, `otherDistributionAmount` and `collectionIds` could lead to the situation when some users would be unable to claim their funds, because the funds had already been claimed by other users.\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L300-L302\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L315\n\n##### Recommendation\nWe recommend adding the following check: `require(!distributionEvents[_distributionEventId].amountPaidIn, \"Cannot update parameters\");`.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#1-some-distribution-parameters-cannot-be-updated-after-funds-sending", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Some tokens could be left on the contract", + "content": "##### Description\nThe manager can update the token address before all tokens were distributed among fans. This can block some tokens on the contract and fans can receive tokens from other distributions.\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L614\n\n##### Recommendation\nWe recommend adding a check that the transferred tokens were distributed or closed by athletes.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#2-some-tokens-could-be-left-on-the-contract", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "TransferFrom from `address(this)` will not work for most of the tokens", + "content": "##### Description\nHere `transferFrom(address(this),...)` is used which will not work with most of the tokens without calling `approve`.\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L647-L651\n\n##### Recommendation\nWe recommend using `SafeTransfer` instead of `TransferFrom`.\n\n\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#3-transferfrom-from-addressthis-will-not-work-for-most-of-the-tokens", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Not enough checks for collections shares", + "content": "##### Description\nThere are not enough checks on the collections shares (tournament and others) which could lead to an unfair distribution of rewards for users. If `sum(tournamentTokenShare1e7_i) > 1e7 * tournamentBPS / 10_000` , then not all users will be able to claim rewards.\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L225-L232\n\n##### Recommendation\nWe recommend adding two checks:\n`sum(tournamentTokenShare1e7_i) <= 1e7 * tournamentBPS / 10_000`\n`sum(otherTokenShare1e7_i) <= 1e7 * otherBPS / 10_000`.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#4-not-enough-checks-for-collections-shares", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "`_athleteSecondarySalesBPS` and `_fantiumSecondarySalesBPS` should be restricted", + "content": "##### Description\n`_athleteSecondarySalesBPS` and `_fantiumSecondarySalesBPS` should be restricted because they will be used in other contracts to calculate royalties with base point = 1 / 10_000, so if `_athleteSecondarySalesBPS + _fantiumSecondarySalesBPS > 10_000`, the royalty will be > 100%. Due to this all transactions with royalty payments will revert.\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L526-L527\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L544-L545\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L658-L659\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L752-L753\n\n##### Recommendation\nWe recommend adding the following check: `_athleteSecondarySalesBPS + _fantiumSecondarySalesBPS <= 10_000`.\n\n\n\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#5-_athletesecondarysalesbps-and-_fantiumsecondarysalesbps-should-be-restricted", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "`maxInvocations` should be limited", + "content": "##### Description\nTokenId contains collactionId, versionId and tokenNumber. `maxInvocations` is a parameter that determines the max tokenNumber. Due to using versionId, tokenNumber should be < 10_000, otherwise the versionId logic would be broken.\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L528\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L691\n\n##### Recommendation\nWe recommend adding the following check: `maxInvocations < 10_000`.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#6-maxinvocations-should-be-limited", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "`trustedForwarder` can be used to impersonate any account or contract", + "content": "##### Description\nThere is an overriden `_msgSender()` function https://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L993 which allows the `trustedForwarder` address owner to specify any address being used as `sender`. This function is used at some of the key parts of the protocol. For example, in the `upgradeTokenVersion` function - https://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L790. Someone's address and allowance can also be used during mint - https://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L350. In case `trustedForwarder` is compromised, it can lead to the funds loss.\n\n##### Recommendation\nWe recommend introducing a multisig wallet on the `trustedForwarder` account or disabling the usage of the `_msgSender()` function on the key parts of the protocol.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#7-trustedforwarder-can-be-used-to-impersonate-any-account-or-contract", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "An incorrect expression inside `require` leads to a revert", + "content": "##### Description\nThere is a `closeDistribution` function - https://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L624. It is used by the protocol manager to close a distribution event and transfer the remaining funds to the athlete. But the first require here https://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L632 uses an assignment operator instead of a logic operator. It always assigns a false `closed` parameter on a distribution event and uses `false` as a `require` argument that leads to an unconditional revert. There is also a second `require` check https://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L636 which uses an incorrect operator too.\n\n##### Recommendation\nWe recommend using a logic operator == inside the mentioned `require` statements.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#8-an-incorrect-expression-inside-require-leads-to-a-revert", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Not checking the ERC20 transfer result on depositing funds by an athlete", + "content": "##### Description\nThere is an `addDistributionAmount` function which transfers funds from an athlete to the protocol. It uses the `transferFrom` function here - https://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L277. If `payoutToken` which returns false/true instead of reverting on an unsuccessful transfer would be used there, then an athlete would be able to mark the event as `amountPaidIn` without depositing any tokens.\n\n##### Recommendation\nWe recommend using `safeTranferFrom` from the OpenZeppelin `safeERC20` implementation.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#9-not-checking-the-erc20-transfer-result-on-depositing-funds-by-an-athlete", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Funds sent by an athlete to a closed distribution are impossible to return", + "content": "##### Description\nIt's possible for an athlete to send funds to a closed distribution with `FantiumClaimingV1.addDistributionAmount()` if they were not sent before (https://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L253). After that it will be impossible to return them to the athlete (it's possible to call`FantiumClaimingV1.closeDistribution()` only for non-closed distributions). For example, it can happen if the incorrect distribution was created by the manager, the manager closed the distribution and recreated it. And by mistake the athlete called `FantiumClaimingV1.addDistributionAmount()` with an id of the closed one.\n\n##### Recommendation\nIt's recommended to add a check to `FantiumClaimingV1.addDistributionAmount()` that the distribution is not closed.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#10-funds-sent-by-an-athlete-to-a-closed-distribution-are-impossible-to-return", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Updating a token version can cause a jump of tokens between collections", + "content": "##### Description\nOne collection can store only 1_000_000 token ids and one version can store maximum 10_000 of token ids that means a token version can be updated only 100 times. Moreover, updating the token version the 100th time will cause a jump of this token to the next collections.\n\n##### Recommendation\nWe recommend expanding the number of updates for one token without limiting further the `maxInvocation` parameter in one collection and adding a check that `tokenVersionUpgrade` doesn't jump between collections [here](https://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L812).\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#11-updating-a-token-version-can-cause-a-jump-of-tokens-between-collections", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Inconsistent shares upgrade", + "content": "##### Description\nAfter shares update in the NFT contract https://github.com/FantiumAG/smart-contracts/blob/c622b4c35132167bacc22cf76656d80715edb5fd/contracts/FantiumNFTV3.sol#L638-L640 `tournamentDistributionAmount` and `otherDistributionAmount` should be updated for all distributions for the specific collection, otherwise, there will be inconsistency in the calculations of the amount for the claim.\n\n##### Recommendation\nWe recommend saving the share value in the distribution event and using it in the calculations of the claim amount.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#12-inconsistent-shares-upgrade", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "An incorrect check", + "content": "##### Description\nThere is an incorrect check in the `updateDistribtionTotalEarningsAmounts()` function https://github.com/FantiumAG/smart-contracts/blob/c622b4c35132167bacc22cf76656d80715edb5fd/contracts/claiming/FantiumClaimingV1.sol#L326-L327. Instead of a check for `_totalTournamentEarnings` and `_totalOtherEarnings` there should be a check for `tournamentDistributionAmount` and `otherDistributionAmount` after calling the `triggerClaimingSnapshot` function. Otherwise, the manager could reduce `tournamentDistributionAmount` and `otherDistributionAmount` by mistake and block the distribution (the athlete will not be able to add tokens and will also close the distribution).\n\n##### Recommendation\nWe recommend adding a check for `tournamentDistributionAmount` and `otherDistributionAmount` after calling the `triggerClaimingSnapshot` function. Also, the same check should be added to the `updateDistributionEventCollectionIds` function.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#13-an-incorrect-check", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "It's possible to top up a closed distribution", + "content": "##### Description\nIf the manager calls by mistake `updateDistribtionTotalEarningsAmounts()` or `updateDistributionEventCollectionIds()` for a closed distribution, it will be topped up using the athlete's funds. These funds will be stuck because it's impossible to close the already closed distribution again.\nhttps://github.com/FantiumAG/smart-contracts/blob/b4acd978e25289becc640f75eb5921e760b83720/contracts/claiming/FantiumClaimingV1.sol#L318\nhttps://github.com/FantiumAG/smart-contracts/blob/b4acd978e25289becc640f75eb5921e760b83720/contracts/claiming/FantiumClaimingV1.sol#L342\n\n##### Recommendation\nWe recommend adding a check to `updateDistribtionTotalEarningsAmounts()` and `updateDistributionEventCollectionIds()`:\n`require(!distributionEvents[_id].closed, \"FantiumClaimingV1: distribution already closed\");`.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#14-its-possible-to-top-up-a-closed-distribution", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Distribution parameters shouldn't be updated after the first claim", + "content": "##### Description\nIf the athlete/manager decides to update the parameters of the distribution event after the tokens have been sent from the claiming contract, it may lead to an unequal distribution of tokens among users. This outcome is inherent in the design. For example, updating the collection IDs while the claiming process is in progress implies that an individual from the previous collection could claim the rewards for themselves and expend some funds from the distribution. Consequently, someone from the new collection may be unable to claim rewards. Updating the `distributionTotalEarningAmounts`signifies that a person who has already claimed rewards might receive lower rewards than those who claimed them later.\n\n##### Recommendation\nWe recommend restricting changes in distribution events and calls to `takeClaimingSnapshot` after the first claim.\n\n\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#15-distribution-parameters-shouldnt-be-updated-after-the-first-claim", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Incorrect event emitting", + "content": "##### Description\nHere https://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L386 the event should be `emit Mint(_to, tokenId + i);`.\n\n##### Recommendation\nWe recommend changing the event to the `emit Mint(_to, tokenId + i);`.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#1-incorrect-event-emitting", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Incorrect input data could break the collection", + "content": "##### Description\nHere https://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L524-L525 the `_athletePrimarySalesBPS <= 10_000` check should be added. If `_athletePrimarySalesBPS` is > 10_000, then the collection mint would revert because of the underflow.\n\n##### Recommendation\nWe recommend adding the following check: `_athletePrimarySalesBPS <= 10_000`.\n\n\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#2-incorrect-input-data-could-break-the-collection", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Unsafe transfer", + "content": "##### Description\nSome of the tokens do not revert on an unsuccessful transfer. We recommend using the OZ safeTrasnfer method instead of a basic transfer method.\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L409-L413\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L417-L421\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L591\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L595\n\n##### Recommendation\nWe recommend using the OpenZeppelin safeTransfer library.\n\n\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#3-unsafe-transfer", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "`nextCollectionId` should be limited", + "content": "##### Description\nDue to unnecessary checks on tokenId in claiming, contract `nextCollectionId` should be limited. Otherwise, claiming functionality for tokens of collection with an id >= 100_000 will revert.\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L522\n\n##### Recommendation\nWe recommend adding the following check: `nextCollectionId < 1_000_000`.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#4-nextcollectionid-should-be-limited", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Collection shares should be limited", + "content": "##### Description\nShares cannot be > 1e7, otherwise claiming will always revert.\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L547-L553\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L694-L701\n\n##### Recommendation\nWe recommend adding the following check:\n`_tournamentTokenShare1e7 <= 1e7 && _otherTokenShare1e7 <= 1e7`.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#5-collection-shares-should-be-limited", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "`maxInvocations` cannot be reduced during an update", + "content": "##### Description\n`maxInvocations` cannot be reduced during an update because it will lead to insolvency in the protocol.\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L691\n\n##### Recommendation\nWe recommend adding the following check:\n`_maxInvocations > collections[_collectionId].maxInvocations`.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#6-maxinvocations-cannot-be-reduced-during-an-update", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Modifier `onlyValidCollectionId()` is missing", + "content": "##### Description\nModifier `onlyValidCollectionId()` should be added here:\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L748-L749\n\n##### Recommendation\nWe recommend adding the `onlyValidCollectionId()` modifier.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#7-modifier-onlyvalidcollectionid-is-missing", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Distribution logic is too flexible", + "content": "##### Description\nNow, the data to calculate the amount for a claim is distributed between the NFT and Claiming contracts. The current architecture may lead to the incorrect distribution of tokens among token holders due to a mistake while updating some collection parameters (e.g. `otherTotalBPS` and `tournamentTotalBPS` should be equal among all collections that are set for distribution; also, there should be a complex check for the collections share to guarantee a fair distribution of rewards among token holders).\n\n##### Recommendation\nWe recommend improving the code, so it would still be working according to the desired buiseness logic, but it would minimize the risk of mistakes during the collection parameters update. We recommend implementing the steps below:\n1. `tournamentBPS` and `otherBPS` should be moved from the NFT contract to the Claiming contract.\n2. Two additional checks should be added while setting up a distribution event:\nCheck 1:\n```solidity=\nuint256 a = _tournamentDistributionAmount * 10_000 / tournamentBPS;\nuint256 b = a * sum(collection_i_maxInvocations \n * collection_i_tournamentShare / 1e7);\nrequire(b == _tournamentDistributionAmount);\n```\n\nCheck 2:\n```solidity=\nuint256 a = _otherDistributionAmount * 10_000 / otherBPS;\nuint256 b = a * sum(collection_i_maxInvocations \n * collection_i_otherShare / 1e7);\nrequire(b == _otherDistributionAmount);\n```\n\n3. The `maxInvocations` parameter cannot be updated during the active distribution for the collection.\n4. `collection_i_otherShare` and `collection_i_tournamentShare` should be saved in the distribution event, so these parameters could be seamlessly updated in a collection.\n\nAlso, Check 1 and Check 2 should be used in both `updateDistributionEventAmount()` functions in the Claiming contract.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#8-distribution-logic-is-too-flexible", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "`fantiumFeeBPS` should be restricted", + "content": "##### Description\n`fantiumFeeBPS` should be <= 10_000, otherwise a claim call will always revert.\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L242\n\n##### Recommendation\nWe recommend adding the following check: `fantiumFeeBPS <= 10_000`.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#9-fantiumfeebps-should-be-restricted", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "An unsafe transfer", + "content": "##### Description\nSome of the tokens do not revert on failed `transferFrom`. Also, there are some tokens with a fee on transfer, so the real transferred balance should be checked via `balanceOf()`, otherwise it could lead to funds insolvency.\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L277-L281\n\n##### Recommendation\nWe recommend using the `safeTransfer` library and also adding a check that an exact amount of tokens was transferred to the contract.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#10-an-unsafe-transfer", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Check for the collection existence is missing", + "content": "##### Description\nThere is no check that the collection exists.\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L315\n\n##### Recommendation\nWe recommend adding a check that the collection exists.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#11-check-for-the-collection-existence-is-missing", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Possible division by zero", + "content": "##### Description\nThere are not enough checks to guarantee there will be no division by zero.\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L520\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L527\n\n##### Recommendation\nWe recommend adding a check that if `tournamentTotalBPS == 0`, then `tournamentClaim = 0` and the same check for `otherTotalBPS == 0`.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#12-possible-division-by-zero", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Distribution closing shouldn't be allowed during the active distribution", + "content": "##### Description\nThere are no checks that the distribution ended in the closing function.\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L624-L631\n\n##### Recommendation\nWe recommend adding a check that the distribution can be closed only when `block.timestamp > closeTime`.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#13-distribution-closing-shouldnt-be-allowed-during-the-active-distribution", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "The collection existence check is missing", + "content": "##### Description\nThere is no check that the collection exists.\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/utils/FantiumUserManager.sol#L202\n\n##### Recommendation\nWe recommend adding a check that the collection exists.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#14-the-collection-existence-check-is-missing", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Variable shadowing", + "content": "##### Description\nThere is a `trustedForwarder` variable being set inside the `initialize` function - https://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L199. The function parameter has the same length as a state variable. In fact, the state variable value doesn't change.\n\n##### Recommendation\nWe recommend changing the function parameter name to `_trustedForwarder`.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#15-variable-shadowing", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "The NFT contract allows multiple ways to avoid KYC", + "content": "##### Description\n\nThe KYC system for NFT minting does not work. Some easy ways:\n1) `FantiumNFTV3.batchMintTo()` checks that `msg.sender` is KYCed but allows specifying `to` who will receive the minted NFT. So, the true NFT receiver is not KYCed.\n- https://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L325-L388\n3) NFT is transferable. So, a KYCed account can buy an NFT and transfer it to anyone.\n\n##### Recommendation\n\nWe recommend making necessary changes for the KYC system or removing it.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#16-the-nft-contract-allows-multiple-ways-to-avoid-kyc", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Hardcoded values for amounts of ERC20 tokens", + "content": "##### Description\n[Here](https://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L220), the value of 10 billion payout tokens is hardcoded as $10_000_000_000_000_000, which is equal to 10 billion multiplied by 10^6. If the `payoutToken` is changed in the future with a different `decimals` value, then the contract will need to be redeployed with a new hardcoded value.\n\n##### Recommendation\nWe recommend using `ERC20(payoutToken).decimals()` to obtain the decimal multiplier instead of a hardcoded value for more flexibility.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#17-hardcoded-values-for-amounts-of-erc20-tokens", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "A manager could transfer funds to the Claiming contract instead of the athlete", + "content": "##### Description\nA manager could transfer funds to the Claiming contract instead of the athlete here https://github.com/FantiumAG/smart-contracts/blob/c622b4c35132167bacc22cf76656d80715edb5fd/contracts/claiming/FantiumClaimingV1.sol#L303.\n\n##### Recommendation\nWe recommend using the athlete's address instead of `_msgSender()`.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#18-a-manager-could-transfer-funds-to-the-claiming-contract-instead-of-the-athlete", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Claiming could be blocked", + "content": "##### Description\nUsers that were able to claim before the manager calls this function https://github.com/FantiumAG/smart-contracts/blob/c622b4c35132167bacc22cf76656d80715edb5fd/contracts/claiming/FantiumClaimingV1.sol#L316-L337 will have to wait until the athlete transfers tokens.\n\n##### Recommendation\nWe recommend calling `addDistributionAmount` in the `updateDistribtionTotalEarningsAmounts()` and `updateDistributionEventCollectionIds` functions.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#19-claiming-could-be-blocked", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "The check can be manipulated", + "content": "##### Description\nA platform manager can by mistake update shares in the NFT contract and call `takeClaimingSnapshot` which will lead to the situation where the athlete should add more funds to the distribution before closing it https://github.com/FantiumAG/smart-contracts/blob/c622b4c35132167bacc22cf76656d80715edb5fd/contracts/claiming/FantiumClaimingV1.sol#L754. \n\n##### Recommendation\nWe recommend changing the `closeDistribution` function.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#20-the-check-can-be-manipulated", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Incorrect work with decimals", + "content": "##### Description\n`DistributionEvent.totalTournamentEarnings` and `DistributionEvent.totalOtherEarnings` are stored for the current token's decimals (https://github.com/FantiumAG/smart-contracts/blob/c622b4c35132167bacc22cf76656d80715edb5fd/contracts/claiming/FantiumClaimingV1.sol#L63). If the new token is set with an other number of decimals after the distribution is created, these variables will contain incorrect values. Therefore, `DistributionEvent.tournamentDistributionAmount` and `DistributionEvent.otherDistributionAmount` will contain incorrect values as well (https://github.com/FantiumAG/smart-contracts/blob/c622b4c35132167bacc22cf76656d80715edb5fd/contracts/claiming/FantiumClaimingV1.sol#L698). This will lead to an incorrect amount of distributed funds.\n\n##### Recommendation\nWe recommend storing `totalTournamentEarnings` and `totalOtherEarnings` without decimals. In such cases `amountPaidIn`, `tournamentDistributionAmount`, and `otherDistributionAmount` should be stored without decimals too.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#21-incorrect-work-with-decimals", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Unnecessary check reverts function call.", + "content": "##### Description\nIt's impossible to call `updateDistributionEventCollectionIds()` or `updateDistribtionTotalEarningsAmounts()` if `tournamentDistributionAmount`+`otherDistributionAmount` stays the same. `topUpDistributionEvent()` reverts if it's not needed to transfer additional funds from the athlete's address. \nhttps://github.com/FantiumAG/smart-contracts/blob/b4acd978e25289becc640f75eb5921e760b83720/contracts/claiming/FantiumClaimingV1.sol#L536\nSo, `updateDistributionEventCollectionIds()` and `updateDistribtionTotalEarningsAmounts()` revert too in such cases. But the manager may want to change these parameters while the total distribution amount stays the same. For example, they want to change the collections' order, from one collection to another with identical parameters. Or they want to set another ratio between tournamentEarnings and otherEarnings.\n\n##### Recommendation\nWe recommend removing a check `payInAmount > 0` from `topUpDistributionEvent()`.\n\n\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#22-unnecessary-check-reverts-function-call", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Anyone can block the payout token by changing its amount by 1 wei", + "content": "##### Description\nThere is a check in `updatePayoutToken()` that the balance should be 0.\nhttps://github.com/FantiumAG/smart-contracts/blob/b4acd978e25289becc640f75eb5921e760b83720/contracts/claiming/FantiumClaimingV1.sol#L749\nSo, anyone can send 1 wei to the balance and make it impossible to change the payout token.\n\n##### Recommendation\nWe recommend removing a zero balance check from `updatePayoutToken()`. Now it's not required because the token address is stored in the snapshot.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#23-anyone-can-block-the-payout-token-by-changing-its-amount-by-1-wei", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "A missed requirement", + "content": "##### Description\nAlthough there is a check in the `takeClaimingSnapshot` function (https://github.com/FantiumAG/smart-contracts/blob/b4acd978e25289becc640f75eb5921e760b83720/contracts/claiming/FantiumClaimingV1.sol#L686), it is more crucial to include it in the `updateDistributionEventCollectionIds()` function (https://github.com/FantiumAG/smart-contracts/blob/b4acd978e25289becc640f75eb5921e760b83720/contracts/claiming/FantiumClaimingV1.sol#L354). Implementing this check makes the previous check unnecessary, as it becomes impossible to set an empty collectionIds array for the distribution event.\n\n##### Recommendation\nWe recommend adding the check `distributionEvents[_distributionEventId].collectionIds.length > 0` to the `updateDistributionEventCollectionIds()` function.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#24-a-missed-requirement", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "`takeClaimingSnapshot()` call will lead to an inconsistent state", + "content": "##### Description\nThis function can block the ongoing distribution event until the funds are paid or the event parameters are returned back.\nhttps://github.com/FantiumAG/smart-contracts/blob/b4acd978e25289becc640f75eb5921e760b83720/contracts/claiming/FantiumClaimingV1.sol#L689\n\n##### Recommendation\nWe recommend removing this function or adding a `topUpDistributionEvent()` call at the end of the function.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#25-takeclaimingsnapshot-call-will-lead-to-an-inconsistent-state", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Possible incorrect event emitting", + "content": "##### Description\nThere are no checks whether an address was previously kyced or not, so it is possible that events will be emited > 1.\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L229\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L240\n\n##### Recommendation\nWe recommend adding a check that a user doesn't have kyc or was already removed from kyc.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#1-possible-incorrect-event-emitting", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "A function can be called with `amount == 0`", + "content": "##### Description\nA function can be called with `amount == 0`.\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L325-L329\n\n##### Recommendation\nWe recommend adding an `amount > 0` check.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#2-a-function-can-be-called-with-amount-0", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Minting insolvency", + "content": "##### Description\nIt is better to use require, because some integrations could break with the current logic.\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L331\n\n##### Recommendation\nWe recommend using require to restrict the function calling with `amount > 10`.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#3-minting-insolvency", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Unnecessary checks", + "content": "##### Description\nThere are some checks that are unnecessary, so they can be removed.\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L349-L353\n\n##### Recommendation\nWe recommend removing these checks.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#4-unnecessary-checks", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "A zero address check", + "content": "##### Description\nSome tokens could be lost because the address is set to zero.\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L543\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L241\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/utils/FantiumUserManager.sol#L79-L80\n\n##### Recommendation\nWe recommend adding a check that the address is not zero.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#5-a-zero-address-check", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "A front-run risk", + "content": "##### Description\nIt is possible to buy NFTs cheaper before the price update.\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L692\n\n##### Recommendation\nWe recommend using a private transactions pool for the price updating.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#6-a-front-run-risk", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "An unchecked timestamp", + "content": "##### Description\nThere are not enough timestamp checks.\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L719\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L536\n\n##### Recommendation\nWe recommend adding checks to make sure that a new timestamp cannot be less than the current timestamp (block.timestamp).\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#7-an-unchecked-timestamp", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Events missing", + "content": "##### Description\nThere are missing events for the important variables update.\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L826\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L841\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L977\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L607\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L614\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L621\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L647-L651\n\n##### Recommendation\nWe recommend adding events emitting on these parameters update.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#8-events-missing", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Bad UX on claiming", + "content": "##### Description\nAfter claiming a user will lose all approvals on their tokens which can be inconvenient.\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L803\n\n##### Recommendation\nWe recommend adding information for users that they will lose approvals on their tokens after claiming.\n\n\n\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#9-bad-ux-on-claiming", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "An inconvenient token update", + "content": "##### Description\nAfter the token update each collection price should be updated.\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L841\n\n##### Recommendation\nWe recommend using only tokens with the same price.\n\n\n\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#10-an-inconvenient-token-update", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Initialization front-running", + "content": "##### Description\nIt is possible to front-run initialization of the Claiming contract.\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L135-L150\n\n##### Recommendation\nWe recommend checking that the Claiming contract was initialized correctly before setting its address to the NFT contract.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#11-initialization-front-running", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "No `forwarder` address check", + "content": "##### Description\nThere are no checks on the `forwarder` address in the initialize function.\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L160-L162\n\n##### Recommendation\nWe recommend adding a check for the `forwarder` address.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#12-no-forwarder-address-check", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Bad work with decimals", + "content": "##### Description\n6 decimals are hardcoded in the Claiming contract which can lead to incorrect work with token amounts in the future.\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L218-L220\n\n##### Recommendation\nWe recommend adjusting work with decimals to make it more flexible.\n\n\n\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#13-bad-work-with-decimals", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "An unnecessary parameter", + "content": "##### Description\n`_amountWithDecimals` is unnecessary in the `addDistributionAmount()` function.\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L262-L269\n\n##### Recommendation\nWe recommend using `distributionEvents[_distributionEventId].tournamentDistributionAmount + distributionEvents[_distributionEventId].otherDistributionAmount` instead.\n\n\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#14-an-unnecessary-parameter", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Unused logic", + "content": "##### Description\nThere is a lot of unused logic in the Manager contract.\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/utils/FantiumUserManager.sol#L95-L140\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/utils/FantiumUserManager.sol#L185-L242\n\n##### Recommendation\nWe recommend removing unused logic.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#15-unused-logic", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Unchecked range for time", + "content": "##### Description\nThere are not enough checks for `_startTime` and `_closeTime` in the Claiming contract.\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L208-L211\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L352-L353\n\n##### Recommendation\nWe recommend adding a check that `_startTime > block.timestamp`, also a new `_startTime` cannot be less than the previous `_startTime`.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#16-unchecked-range-for-time", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Unnecessary checks", + "content": "##### Description\nThere are several unnecessary checks.\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L408-L412\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L636-L639\n\n##### Recommendation\nWe recommend removing unnecessary checks.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#17-unnecessary-checks", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Not checking the length on `_addresses` and `_increaseAllocations`", + "content": "##### Description\nAt line https://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L262 the `batchAllowlist` function is defined. It takes two arrays as an argument and then loops over them. It is expected that two arrays would have the same length as they contain corresponding data. But their lengths aren't compared.\n\n##### Recommendation\nWe recommend comparing that the arrays have the same lengths.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#18-not-checking-the-length-on-_addresses-and-_increaseallocations", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Unnecessary casting to `uint256`", + "content": "##### Description\nUnnecessary casts were spotted here - https://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L580 and here - https://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/FantiumNFTV3.sol#L462.\n\n##### Recommendation\nIt's not recommended to cast to `uint256` there, as arguments have the `uint256` types themselves.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#19-unnecessary-casting-to-uint256", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "`onlyManager()` and `onlyRole(PLATFORM_MANAGER_ROLE)` have the same logic", + "content": "##### Description\nThere are some places where the `onlyManager()` modifier is used - https://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L201 and `onlyRole(PLATFORM_MANAGER_ROLE)` - https://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L298. Those modifiers have the same logic. There is no need to use both of them.\n\n##### Recommendation\nWe recommend coming to a one type of modifier when checking that the user is the protocol manager.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#20-onlymanager-and-onlyroleplatform_manager_role-have-the-same-logic", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Equation can be simplified", + "content": "##### Description\nThe calculation of the token collection can be simplified.\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/utils/TokenVersionUtil.sol#L21-L22\n\n##### Recommendation\nWe recommend changing the calculation to `uint256 collectionOfToken = _tokenId /ONE_MILLION;`.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#21-equation-can-be-simplified", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Bad name for the function", + "content": "##### Description\nTh function name was copypasted from the previous function.\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L306-L309\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L338-L342\n\n##### Recommendation\nWe recommend changing the function name.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#22-bad-name-for-the-function", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "A function can be optimized", + "content": "##### Description\nThe function can be optimized in two places:\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L548-L560\nhttps://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L553-L558.\n\n##### Recommendation\nWe recommend adding `if(!tokenNrClaimed)` before the loop and `break` inside `if` in the loop.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#23-a-function-can-be-optimized", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Bad pause management", + "content": "##### Description\nPause management is very inconvenient right now, because all manager functions pause with the user functions which blocks the manager from making changes in the contract.\n\n##### Recommendation\nWe recommend rebuilding pause management and giving to the manager the ability to change some important parameters when the contract is paused.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#24-bad-pause-management", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "A limit of the distribution amount as one billion is not correct", + "content": "##### Description\nFantiumClaimingNFTV1 has these lines:\n- https://github.com/FantiumAG/smart-contracts/blob/a2d126453c1105028f12277b8f342d2cdbf01a77/contracts/claiming/FantiumClaimingV1.sol#L216-L222.\nThe comments state that it should \"check if the amount is less than a billion\".\nBy the way, it compares with number `10_000_000_000_000_000`, which is in fact ten billion with 6 decimals.\n\n##### Recommendation\nWe recommend updating either the comparison or the comment to adjust to true designed limitations.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#25-a-limit-of-the-distribution-amount-as-one-billion-is-not-correct", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Version calculation can be simplified", + "content": "##### Description\nToken's version calculation can be simplified. Now it's calculated as \n`((_tokenId % ONE_MILLION) - (_tokenId % TEN_THOUSAND)) / TEN_THOUSAND` (https://github.com/FantiumAG/smart-contracts/blob/c622b4c35132167bacc22cf76656d80715edb5fd/contracts/utils/TokenVersionUtil.sol#L22). But it's equal to `(_tokenId % ONE_MILLION) / TEN_THOUSAND`.\n\n##### Recommendation\nWe recommend simplifying the version calculation.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#26-version-calculation-can-be-simplified", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "An unnecessary internal function onlyRole modifier", + "content": "##### Description\nThe internal function `FantiumClaimingV1.triggerClaimingSnapshot()` has a `onlyRole(PLATFORM_MANAGER_ROLE)` modifier (https://github.com/FantiumAG/smart-contracts/blob/c622b4c35132167bacc22cf76656d80715edb5fd/contracts/claiming/FantiumClaimingV1.sol#L665). This function can't be called from outside, so any role modifier is unnecessary. Also, every function calling `triggerClaimingSnapshot()` already has this modifier.\n\n##### Recommendation\nWe recommend removing this modifier.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#27-an-unnecessary-internal-function-onlyrole-modifier", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "`payOutToken` and `payoutToken` variables differ only in one symbol.", + "content": "##### Description\nIt's easy to make a mistake using variables `payOutToken` and `payoutToken`. It's better to use another name for the local variable.\n\n##### Recommendation\nWe recommend using another name for `payOutToken`.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#28-payouttoken-and-payouttoken-variables-differ-only-in-one-symbol", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Functions `topUpDistributionEvent()` and `addDistributionAmount()` have duplicated functionality.", + "content": "##### Description\nFunctions `topUpDistributionEvent()` and `addDistributionAmount()` have duplicated functionality.\n\n##### Recommendation\nWe recommend taking out the logic to one function.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#29-functions-topupdistributionevent-and-adddistributionamount-have-duplicated-functionality", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "The `maxInvocations` parameter check", + "content": "##### Description\nThe FantiumNFTV3 contract allows to set off the `maxInvocations` parameter for collection and change its value in the future. Current checks allow not more than 9999 tokens (`maxInvocations < 10000`) (Max token id inside one token version would be 9998).\n\n##### Recommendation\nWe recommend using a non-strict (<=) check instead of a strict one (<).\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#30-the-maxinvocations-parameter-check", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "An unnecessary check", + "content": "##### Description\nThere is an unnecessary check inside the `claim` function. It compares `closeTime` with a 0 value despite the fact that such value cannot ever be set to that parameter.\n\n##### Recommendation\nWe recommend removing that check.\n", + "protocol": "Fantium", + "report_date": "2023-05-04", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/README.md#31-an-unnecessary-check", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium%20v2/Fantium%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Double-approval attack by malicious owner", + "content": "##### Description\n\nPending transactions have the `_approvalCount` counter.\n\nThe `_approvalCount` for each transaction is simply incremented by 1 each time an owner approves it. However, when the owners are reconfigured using the `configureOwners()` function, the `_approvalCount` value for valid transactions remains positive. This can lead to a scenario where the minority of owners can execute a transaction.\n\n- https://github.com/cloudwalk/brlc-multisig/blob/b5d6c2b6273162d5666d48649890b15a113df7a7/contracts/base/MultiSigWalletBase.sol#L345\n- https://github.com/cloudwalk/brlc-multisig/blob/b5d6c2b6273162d5666d48649890b15a113df7a7/contracts/base/MultiSigWalletBase.sol#L370\n\nFor example, in a wallet requiring the 2/3 of approvals, a malicious owner can create a transaction to withdraw all funds and approve it. They can then claim their account has been hacked and ask the other owners to change their account address (using `configureOwners()`). After the address change, the malicious owner can approve the previously created transaction again reaching the minimum required approvals=2 and execute the transaction.\n\n##### Recommendation\n\nWe recommend removing the counter and checking approvals in `_execute()` by iterating through `_approvalStatus()` using current owners.\n\nLike here in Gnosis:\n- https://github.com/gnosis/MultiSigWallet/blob/90639984c960d281bed3e0a5d56dd4adcb9407c4/contracts/MultiSigWallet.sol#L267-L279.\n\n", + "protocol": "CloudWalk", + "report_date": "2023-04-27", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/CloudWalk/README.md#1-double-approval-attack-by-malicious-owner", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/CloudWalk/CloudWalk%20Multisig%20Wallet%20Audit%20Report.pdf" + }, + { + "title": "`_execute` allows you to execute unsuccessful tasks in the future", + "content": "##### Description\n\nIf the transaction is unsuccessful, then a revert will occur in the code (https://github.com/cloudwalk/brlc-multisig/blob/b5d6c2b6273162d5666d48649890b15a113df7a7/contracts/base/MultiSigWalletBase.sol#L378):\n\n```\n(bool success, bytes memory data) = transaction.to.call{ \n value: transaction.value \n}(transaction.data);\nif (!success) {\n revert InternalTransactionFailed(data);\n}\n```\n\nHowever, if a condition allows the transaction to be executed later, it will be completed as success. This is especially dangerous for:\n- `expirationTime` as `365 days`\n- various swaps with a slippage\n- `configureOwners` method and others. \n\n##### Recommendation\nWe recommend disallowing to use the transaction after `revert`, because the permission to execute remains with this transaction.\n\n", + "protocol": "CloudWalk", + "report_date": "2023-04-27", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/CloudWalk/README.md#1-_execute-allows-you-to-execute-unsuccessful-tasks-in-the-future", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/CloudWalk/CloudWalk%20Multisig%20Wallet%20Audit%20Report.pdf" + }, + { + "title": "A transaction doesn't have the sequence information", + "content": "##### Description\n\nIn case of multiple transactions are approved any owner is able to choose the sequense of transactions. In some cases this owner can extract additional benefits from choosing the ordering.\n\nIn addition, transactions allow only one target call per transaction - it may be not enough for DeFi interactions. Complex DeFi interactions require making a few approved transactions, so benefits from sequencing can arise.\n\n- https://github.com/cloudwalk/brlc-multisig/blob/b5d6c2b6273162d5666d48649890b15a113df7a7/contracts/base/IMultiSigWallet.sol#L11-L18\n- https://github.com/cloudwalk/brlc-multisig/blob/b5d6c2b6273162d5666d48649890b15a113df7a7/contracts/base/MultiSigWalletBase.sol#L378\n\n##### Recommendation\n\nWe recommend adding the nonce information in transactions and allowing a list of targets.\n", + "protocol": "CloudWalk", + "report_date": "2023-04-27", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/CloudWalk/README.md#2-a-transaction-doesnt-have-the-sequence-information", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/CloudWalk/CloudWalk%20Multisig%20Wallet%20Audit%20Report.pdf" + }, + { + "title": "`WalletUpgradable` initialization is risky", + "content": "##### Description\n\nThe current initialization of an upgradable wallet includes multiple steps, where a wallet proxy is owned by some external admin. The admin has to transfer proxy ownership directly to the wallet to finalize the initialization.\n\n##### Recommendation\n\nWe recommend applying the same factory-pattern for wallets as well in order to guarantee correct finalized initialization.\n\nAlso one of the solutions is to use `UUPSUpgradeable` with the correct setting `_authorizeUpgrade()` method via `onlySelfCall`.\n\n", + "protocol": "CloudWalk", + "report_date": "2023-04-27", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/CloudWalk/README.md#1-walletupgradable-initialization-is-risky", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/CloudWalk/CloudWalk%20Multisig%20Wallet%20Audit%20Report.pdf" + }, + { + "title": "`Wallet._configureExpirationTime()` allows setting low values, it's likely for the transactions to be frozen", + "content": "##### Description\n\n`_expirationTime` should be long enough to make a transaction.\nIf it is low or mistakenly set to zero - transactions will be hard to execute.\n- https://github.com/cloudwalk/brlc-multisig/blob/b5d6c2b6273162d5666d48649890b15a113df7a7/contracts/base/MultiSigWalletBase.sol#L314\n\n\n##### Recommendation\n\nWe recommend setting a range for `_expirationTime` with minimum and maximum amounts.\n\n", + "protocol": "CloudWalk", + "report_date": "2023-04-27", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/CloudWalk/README.md#1-wallet_configureexpirationtime-allows-setting-low-values-its-likely-for-the-transactions-to-be-frozen", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/CloudWalk/CloudWalk%20Multisig%20Wallet%20Audit%20Report.pdf" + }, + { + "title": "Transfer ownership in two steps", + "content": "##### Description\nIn the current implementation, the `configureOwners()` function immediately replaces the old owners with the new ones. However, this can lead to a permanent contract lock if it turns out that not all new owners actually control the provided addresses. A safer approach would be to implement a two-step process for changing owners, where the final owner replacement only occurs after all new owners have confirmed their ownership of the specified addresses.\n\n- https://github.com/cloudwalk/brlc-multisig/blob/b5d6c2b6273162d5666d48649890b15a113df7a7/contracts/base/MultiSigWalletBase.sol#L190\n\n##### Recommendation\nIt is recommended to implement a two-step owner replacement process. Instead of immediately replacing the old owners, the function should first require new owners to confirm their ownership of the specified addresses. Only after all new owners have successfully confirmed their ownership, should the final owner replacement take place. This approach reduces the risk of a contract lock due to incorrect or inaccessible owner addresses.\n", + "protocol": "CloudWalk", + "report_date": "2023-04-27", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/CloudWalk/README.md#2-transfer-ownership-in-two-steps", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/CloudWalk/CloudWalk%20Multisig%20Wallet%20Audit%20Report.pdf" + }, + { + "title": "Transaction exposure", + "content": "##### Description\nIn the current implementation, even when `_cooldownTime` is set to 0, users are unable to collect all required approvals and submit a transaction to the private mempool at once. As a result, large trading transactions are visible in the contract state in advance, since the owners must first submit the full transaction data and then approve it through separate transactions. This makes these transactions vulnerable to griefing or profit reduction, as other parties can extract profit by observing the pending transactions and acting accordingly.\n\n- https://github.com/cloudwalk/brlc-multisig/blob/b5d6c2b6273162d5666d48649890b15a113df7a7/contracts/base/MultiSigWalletBase.sol#L316\n\n##### Recommendation\n\nConsider implementing a hidden transaction approach, where instead of storing the full transaction data in the contract storage, only the hash of the transaction is stored. This way, the transaction details remain hidden until the transaction is executed. Once the required number of owners have provided valid signatures for the hashed transaction, the transaction can be executed with the actual transaction data provided during execution. This approach adds an extra layer of privacy and security for large trading transactions.\n", + "protocol": "CloudWalk", + "report_date": "2023-04-27", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/CloudWalk/README.md#3-transaction-exposure", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/CloudWalk/CloudWalk%20Multisig%20Wallet%20Audit%20Report.pdf" + }, + { + "title": "Inability to cancel transactions with long expiration times after owner replacement", + "content": "##### Description\nIn the current implementation, when owners are replaced, transactions with the previously set long `_expirationTime` values continue to remain in the list of pending transactions. New owners are unable to cancel these transactions, potentially allowing malicious transactions to be executed in the future. This poses a security risk, as new owners may not have the desired control over pending transactions submitted by previous owners.\n\n- https://github.com/cloudwalk/brlc-multisig/blob/b5d6c2b6273162d5666d48649890b15a113df7a7/contracts/base/MultiSigWalletBase.sol#L314\n\nNote, that the `revoke()` function cannot help in that case, because it only revokes a single approval of a specific owner and cannot revoke old approvals if the owners are changed.\n\n- https://github.com/cloudwalk/brlc-multisig/blob/b5d6c2b6273162d5666d48649890b15a113df7a7/contracts/base/MultiSigWalletBase.sol#L387\n\n##### Recommendation\n\nTo address this vulnerability, implement a mechanism to either automatically cancel or invalidate all pending transactions when owners are replaced. Alternatively, allow new owners to cancel or reject transactions, providing them with the necessary control over the contract's pending transactions. This will help prevent the execution of unwanted or malicious transactions submitted by the previous owners and ensure that only transactions approved by the current set of owners are executed.\n\n", + "protocol": "CloudWalk", + "report_date": "2023-04-27", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/CloudWalk/README.md#4-inability-to-cancel-transactions-with-long-expiration-times-after-owner-replacement", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/CloudWalk/CloudWalk%20Multisig%20Wallet%20Audit%20Report.pdf" + }, + { + "title": "The Oracle can lock reward distribution", + "content": "##### Description\nIf Oracle updates become unavailable for some reasons, the rewards cannot be distributed.\n\n##### Recommendation\nIt is recommended to introduce a function that can distribute rewards without data from the Oracle.\n\n", + "protocol": "P2P.org", + "report_date": "2023-04-10", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/P2P.org/ETH2%20Depositor%20&%20ETH%20Staking%20Fee%20Distributor%20(v.2)/README.md#1-the-oracle-can-lock-reward-distribution", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/P2P.org/ETH2%20Depositor%20&%20ETH%20Staking%20Fee%20Distributor%20(v.2)/ETH2%20Depositor%20&%20ETH%20Staking%20Fee%20Distributor%20Security%20Audit%20Report%20(v.2).pdf" + }, + { + "title": "Front-running for the `bid()` method", + "content": "##### Description\n\nThe `bid()` transaction (https://github.com/clearpool-finance/permissionless-protocol/blob/f1f38c5ba83e2c3a68155042229b04678d9425ce/contracts/Auction.sol#L105) with a slightly higher bid can be sent right before the end of an auction.\n\nThe winner can be the one who bids a unit more at the last moment. Every bid transaction can be front-run or back-run. Thus, a legitimate bidder can be prevented from making a proper bid.\n\n##### Recommendation\nWe recommended adding a specific step of an auction and taking a bid in `resolveAuction` from the previous block to avoid front-running.\n\n", + "protocol": "Clearpool", + "report_date": "2023-03-31", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/README.md#1-front-running-for-the-bid-method", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/Clearpool%20Security%20Audit%20Report.pdf" + }, + { + "title": "Rejected auction is always in default state", + "content": "##### Description\n\nAfter the auction has been rejected, there is no way for the owner or user to close the pool. So, in `PoolFactory.marketPools`, `PoolFactory.pools` this pool (with default status and rejected auction) will be there for infinity.\n\n```\n// start some auction\n...\nawait auction.resolveAuction(pool.address, false);\n\nawait increaseTime(MUCH_TIME);\n\n// try to close pool after Auction (calls from owner)\n// await pool.allowWithdrawalAfterNoAuction(); \u2014 revert\n// await pool.close(); \u2014 revert\n```\n\n##### Recommendation\nWe recommend adding the description of this state to the whitepaper or adding a conditional to close the pool:\n- https://github.com/clearpool-finance/permissionless-protocol/blob/f1f38c5ba83e2c3a68155042229b04678d9425ce/contracts/pool/PoolBase.sol#L180. \n", + "protocol": "Clearpool", + "report_date": "2023-03-31", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/README.md#2-rejected-auction-is-always-in-default-state", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/Clearpool%20Security%20Audit%20Report.pdf" + }, + { + "title": "Protect CPOOLs in PoolFactory", + "content": "##### Description\n\nThe rewards, which will be paid to the user, are at the factory. \n\n`Sweep` allows to withdraw CPOOL tokens and block the possibility of claiming by users.\n\n- https://github.com/clearpool-finance/permissionless-protocol/blob/f1f38c5ba83e2c3a68155042229b04678d9425ce/contracts/PoolFactory.sol#L393\n\n##### Recommendation\nWe recommended protecting CPOOL to avoid sweeping.\n", + "protocol": "Clearpool", + "report_date": "2023-03-31", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/README.md#3-protect-cpools-in-poolfactory", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/Clearpool%20Security%20Audit%20Report.pdf" + }, + { + "title": "Infinite Block Auction", + "content": "##### Description\n\nThe owner may not call `resolveAuction` (https://github.com/clearpool-finance/permissionless-protocol/blob/f1f38c5ba83e2c3a68155042229b04678d9425ce/contracts/Auction.sol#L139):\n- to block `lastBid` of a user on the `Auction` contract and there is no mechanism to bypass that;\n- to prevent the pool's users from getting an insurance or bid after the auction;\n- to manipulate the market.\n\n##### Recommendation\nWe recommended allowing users to call `resolveAuction` if enough time has passed.\n", + "protocol": "Clearpool", + "report_date": "2023-03-31", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/README.md#4-infinite-block-auction", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/Clearpool%20Security%20Audit%20Report.pdf" + }, + { + "title": "Double-Adding Pool Vulnerability", + "content": "##### Description\n\nThe [`PoolFactory.initializeExistingPoolsByMarket()`](https://github.com/clearpool-finance/permissionless-protocol/blob/f1f38c5ba83e2c3a68155042229b04678d9425ce/contracts/PoolFactory.sol#L214) function may add a pool to the `marketPools` array more than once if the function is called multiple times. This can occur if the function is called by mistake.\n\nThe [`closePool()`](https://github.com/clearpool-finance/permissionless-protocol/blob/f1f38c5ba83e2c3a68155042229b04678d9425ce/contracts/PoolFactory.sol#L402) function is unable to remove more than one instance of the same pool from the `marketPools` array and cannot be called twice for the same pool. As a result, the pool will remain in the array misleading users and also consuming gas when the array is iterated through.\n\n##### Recommendation\n\nIn order to fix this vulnerability, the `initializeExistingPoolsByMarket()` function should include an assertion that checks for the existence of the pool in the marketPools array before adding it. This will ensure that the same pool is not added more than once.\n", + "protocol": "Clearpool", + "report_date": "2023-03-31", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/README.md#5-double-adding-pool-vulnerability", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/Clearpool%20Security%20Audit%20Report.pdf" + }, + { + "title": "Close active pools via `resolveAuctionWithoutGoverment`", + "content": "##### Description\n\nIn commit 68820cb61c8e3fa1714be0aca161d9916c8ac9d3 `resolveAuctionWithoutGoverment` is called without a pool and time filtering. These checks can be passed by the user (https://github.com/clearpool-finance/permissionless-protocol/blob/68820cb61c8e3fa1714be0aca161d9916c8ac9d3/contracts/Auction.sol#L266):\n\n```\n# by default currentAuction.tokenId = 0\nrequire(currentAuction.tokenId == 0, \"AC\");\n# by default currentAuction.end = 0\nrequire(block.timestamp >= currentAuction.end, \"ANF\");\n# block.timestamp >= 6 days\nrequire(block.timestamp - currentAuction.end >= 6 days, \"TNP\");\n\n# lastBidder = 0x0, lastBid = 0\n# some erc-20 tokens allow to `transfer(0x0, 0)`\ncurrency.safeTransfer(\n currentAuction.lastBidder,\n currentAuction.lastBid\n);\n```\n\nSo, anyone can close an active pool at any time and call (https://github.com/clearpool-finance/permissionless-protocol/blob/68820cb61c8e3fa1714be0aca161d9916c8ac9d3/contracts/Auction.sol#L288):\n```\n...\nauctionInfo[pool].tokenId = type(uint96).max;\n...\nIPoolMaster(pool).processDebtClaim();\n...\n```\n\n##### Recommendation\nWe recommend checking the `currentAuction.end` and `pool` variables.\n\nThere is code that can block this flow (https://github.com/clearpool-finance/permissionless-protocol/blob/68820cb61c8e3fa1714be0aca161d9916c8ac9d3/contracts/Auction.sol#L280):\n```\ncurrency.safeTransfer(\n currentAuction.lastBidder,\n currentAuction.lastBid\n);\n```\n\nBut WETH, USDT, etc. can allow to call `transfer(0x0, 0)`.\n\n", + "protocol": "Clearpool", + "report_date": "2023-03-31", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/README.md#6-close-active-pools-via-resolveauctionwithoutgoverment", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/Clearpool%20Security%20Audit%20Report.pdf" + }, + { + "title": "Risks of non-complete initialization", + "content": "##### Description\n\n`PoolFactory.initialize()` is far from being the final initialization.\nIt sets only:\n- `cpool`\n- `staking`\n- `poolBeacon`\n- `interestRateModel`\n- `auction`\n\nBut many of crucial parameters remain not set and require calling a separate function for every parameter.\n- `treasury` - if not set, a reserve token can be transferred to a zero address on pool.proceesAuctionStart(), pool.close()\n- `reserveFactor` - if not set, a pool will work wrong\n- `insuranceFactor` - if not set, a pool will work wrong\n- `warningUtilization` - if not set, a pool will work wrong\n- `provisionalDefaultUtilization` - if not set, a pool will work wrong\n- `warningGracePeriod` - if not set, a pool will work wrong\n- `maxInactivePeriod` - if not set, a pool will work wrong\n- `periodToStartAuction` - if not set, a pool will work wrong\n- `rewardPerSecond` - if not set, cPool token rewards will be set zero, that is ok\n\nIt is not so bad that these parameters are not set during the factory initialization. The problem is that Factory allows createPool() if some of these parameters are not set.\n\n- https://github.com/clearpool-finance/permissionless-protocol/blob/f1f38c5ba83e2c3a68155042229b04678d9425ce/contracts/PoolFactory.sol#L181-201\n\nThis can lead to a situation where a human error causes one of these variables to be undefined, resulting in a new pool being created with incorrect parameters in the `PoolFactory` contract.\n\n##### Recommendation\n\nWe recommend either putting all parameter settings to the initialization function or placing `require(parameter!=0)` for all parameters in _createPool().\n\n", + "protocol": "Clearpool", + "report_date": "2023-03-31", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/README.md#1-risks-of-non-complete-initialization", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/Clearpool%20Security%20Audit%20Report.pdf" + }, + { + "title": "Stake is locked for the contract owner in `_createPool()`", + "content": "##### Description\nThe `_createPool()` method is called from the `createPoolInitial()` and `createPool()` methods which are marked with the `onlyOwner` modifier.\nThus,\n```\ninfo.staker = msg.sender;\ninfo.stakedAmount = staking.lockStake(msg.sender);\n```\nat https://github.com/clearpool-finance/permissionless-protocol/blob/f1f38c5ba83e2c3a68155042229b04678d9425ce/contracts/PoolFactory.sol#L509 uses the owner's address to lock the stake, while it's a manager who is supposed to be staking tokens according to the [whitepaper](https://3929482601-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhkiSI8bK3ThlypJ3jdEC%2Fuploads%2F6DdJZjkGBW4KgNDGTKny%2FClearpool%20Whitepaper%20v2.2.pdf?alt=media&token=c3b9bf3c-c806-43ea-a47b-b914bf885bed):\n\n> 2.1 Borrower Whitelisting & Credit Evaluation\n> <..>\n> To become whitelisted, the institution must first complete a due diligence, KYC and AML procedure, agree to the Clearpool Terms & Conditions, and stake an amount of CPOOL tokens before a pool can be launched.\n\n##### Recommendation\n\nIf it is not an expected behavior, correct the lines so that the funds were taken from the right staker and this right staker were stored in `info.staker`.\n", + "protocol": "Clearpool", + "report_date": "2023-03-31", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/README.md#2-stake-is-locked-for-the-contract-owner-in-_createpool", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/Clearpool%20Security%20Audit%20Report.pdf" + }, + { + "title": "The pool borrower must not be permitted to participate in the auction", + "content": "##### Description\n\nIn `setWhitelistedBidder` there aren't any checks for `bidder` (https://github.com/clearpool-finance/permissionless-protocol/blob/f1f38c5ba83e2c3a68155042229b04678d9425ce/contracts/Auction.sol#L179).\n\nBut in [whitepaper](https://3929482601-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhkiSI8bK3ThlypJ3jdEC%2Fuploads%2F6DdJZjkGBW4KgNDGTKny%2FClearpool%20Whitepaper%20v2.2.pdf?alt=media&token=c3b9bf3c-c806-43ea-a47b-b914bf885bed):\n> 3.3 Auction\n> <..>\n> Bidders can be individuals or institutions but must be whitelisted. Whitelisting is achieved through providing KYC information and by declaring the UBO of the bid. The pool borrower is not permitted to participate in the auction.\n\nIt requires excluding the manager of the pool.\n\n##### Recommendation\n\nAlthough a manager may create a different address, we recommended adding this check to `setWhitelistedBidder`:\n- https://github.com/clearpool-finance/permissionless-protocol/blob/f1f38c5ba83e2c3a68155042229b04678d9425ce/contracts/Auction.sol#L179\n\nOr revising the whitepaper to make this logic more transparent.\n", + "protocol": "Clearpool", + "report_date": "2023-03-31", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/README.md#3-the-pool-borrower-must-not-be-permitted-to-participate-in-the-auction", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/Clearpool%20Security%20Audit%20Report.pdf" + }, + { + "title": "Unused `flashGovernor` variable", + "content": "##### Description\nThe [`PoolFactory.flashGovernor`](https://github.com/clearpool-finance/permissionless-protocol/blob/f1f38c5ba83e2c3a68155042229b04678d9425ce/contracts/PoolFactory.sol#L26) variable is not being used in the code and is always zero.\n\n##### Recommendation\n\nRemove the unused field or mark it as obsolete if it's required for maintaining the storage structure.\n", + "protocol": "Clearpool", + "report_date": "2023-03-31", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/README.md#1-unused-flashgovernor-variable", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/Clearpool%20Security%20Audit%20Report.pdf" + }, + { + "title": "PoolFactory functions `setReserveFactor()` and `setInsuranceFactor()` require additional checks", + "content": "##### Description\n\nTwo versions of these functions found:\n1. in PoolFacrory\n```\nfunction setReserveFactor(uint256 reserveFactor_) external onlyOwner {\n require(reserveFactor_ <= Decimal.ONE, \"GTO\");\n reserveFactor = reserveFactor_;\n emit ReserveFactorSet(reserveFactor_);\n }\n\nfunction setInsuranceFactor(uint256 insuranceFactor_) external onlyOwner {\n require(insuranceFactor_ <= Decimal.ONE, \"GTO\");\n insuranceFactor = insuranceFactor_;\n emit InsuranceFactorSet(insuranceFactor_);\n }\n```\n2. in pools (PoolConfuguration.sol)\n```\nfunction setReserveFactor(uint256 reserveFactor_) external onlyGovernor {\n require(reserveFactor + insuranceFactor <= Decimal.ONE, \"GTO\");\n reserveFactor = reserveFactor_;\n }\n\nfunction setInsuranceFactor(uint256 insuranceFactor_)\n external\n onlyGovernor\n {\n require(reserveFactor + insuranceFactor <= Decimal.ONE, \"GTO\");\n insuranceFactor = insuranceFactor_;\n }\n```\nThe version in the pools checks that the sum of two factors is below Decimal.ONE. The factory setters do not check this, so pools can be created where the sum is above Decimal.ONE.\n\n- https://github.com/clearpool-finance/permissionless-protocol/blob/f1f38c5ba83e2c3a68155042229b04678d9425ce/contracts/PoolFactory.sol#L313-325\n\n##### Recommendation\n\nWe recommend that the two functions should be synchronized and adding the following line to the Factory functions.\n```\nrequire(reserveFactor + insuranceFactor <= Decimal.ONE, \"GTO\");\n```\n", + "protocol": "Clearpool", + "report_date": "2023-03-31", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/README.md#2-poolfactory-functions-setreservefactor-and-setinsurancefactor-require-additional-checks", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/Clearpool%20Security%20Audit%20Report.pdf" + }, + { + "title": "`warningUtilization` can be above `provisionalDefaultUtilization`", + "content": "##### Description\n\n`WarningUtilization` is expected to be always below `ProvisionalDefaultUtilization` but setters do not check this.\n```\nfunction setWarningUtilization(uint256 warningUtilization_)\n external\n onlyOwner\n {\n require(warningUtilization_ <= Decimal.ONE, \"GTO\");\n warningUtilization = warningUtilization_;\n emit WarningUtilizationSet(warningUtilization_);\n }\n\nfunction setProvisionalDefaultUtilization(\n uint256 provisionalDefaultUtilization_\n ) external onlyOwner {\n require(provisionalDefaultUtilization_ <= Decimal.ONE, \"GTO\");\n provisionalDefaultUtilization = provisionalDefaultUtilization_;\n emit ProvisionalDefaultUtilizationSet(\n provisionalDefaultUtilization_\n );\n }\n```\n\n- https://github.com/clearpool-finance/permissionless-protocol/blob/f1f38c5ba83e2c3a68155042229b04678d9425ce/contracts/PoolFactory.sol#L329-346\n\n##### Recommendation\nWe recommend adding the necessary comparison invariants in setters. \n", + "protocol": "Clearpool", + "report_date": "2023-03-31", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/README.md#3-warningutilization-can-be-above-provisionaldefaultutilization", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/Clearpool%20Security%20Audit%20Report.pdf" + }, + { + "title": "Add an auction resolution event", + "content": "##### Description\nThe`resolveAuction()` method at https://github.com/clearpool-finance/permissionless-protocol/blob/f1f38c5ba83e2c3a68155042229b04678d9425ce/contracts/Auction.sol#L139 doesn't emit an event about the auction resolution result.\n\n##### Recommendation\nAdd an event to notify the interested parties about the auction resolution result.\n", + "protocol": "Clearpool", + "report_date": "2023-03-31", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/README.md#4-add-an-auction-resolution-event", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/Clearpool%20Security%20Audit%20Report.pdf" + }, + { + "title": "Parameters not validated for zero address", + "content": "##### Description\nThe methods:\n- `createPoolInitial()` at https://github.com/clearpool-finance/permissionless-protocol/blob/f1f38c5ba83e2c3a68155042229b04678d9425ce/contracts/PoolFactory.sol#L225, \n- `createPool()` at https://github.com/clearpool-finance/permissionless-protocol/blob/f1f38c5ba83e2c3a68155042229b04678d9425ce/contracts/PoolFactory.sol#L238, \n- `transferPool()` at https://github.com/clearpool-finance/permissionless-protocol/blob/f1f38c5ba83e2c3a68155042229b04678d9425ce/contracts/PoolFactory.sol#L246, \n- `setManagerInfo()` at https://github.com/clearpool-finance/permissionless-protocol/blob/f1f38c5ba83e2c3a68155042229b04678d9425ce/contracts/PoolFactory.sol#L268, \n- `setCurrency()` at https://github.com/clearpool-finance/permissionless-protocol/blob/f1f38c5ba83e2c3a68155042229b04678d9425ce/contracts/PoolFactory.sol#L279\n\ndo not validate input for zero address, which allows to add not valid data to the storage.\n\n##### Recommendation\nAdd a zero address validation.\n", + "protocol": "Clearpool", + "report_date": "2023-03-31", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/README.md#5-parameters-not-validated-for-zero-address", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/Clearpool%20Security%20Audit%20Report.pdf" + }, + { + "title": "Excessive Centralization", + "content": "##### Description\nIn the `Auction` and `PoolFactory` contracts, all privileged methods are called by the contract owner.\n\n- https://github.com/clearpool-finance/permissionless-protocol/blob/f1f38c5ba83e2c3a68155042229b04678d9425ce/contracts/PoolFactory.sol\n- https://github.com/clearpool-finance/permissionless-protocol/blob/f1f38c5ba83e2c3a68155042229b04678d9425ce/contracts/Auction.sol\n\n`setPoolAuctionEnd()` can be used by the owner to endlessly extend the auction or to finish it at any moment, for instance, after a certain bid.\n\n##### Recommendation\nIn order to reduce centralization, it may be beneficial to use the OpenZeppelin's `AccessControl` contract to granulate roles. This will allow different roles to be defined and different levels of access to the contract's privileged methods.\n\nThis will enhance the security and decentralization of the contract by allowing multiple parties to have different levels of access and control. It will also make the contract more flexible and adaptable, as different roles can be created and modified as needed.\n", + "protocol": "Clearpool", + "report_date": "2023-03-31", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/README.md#6-excessive-centralization", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/Clearpool%20Security%20Audit%20Report.pdf" + }, + { + "title": "Possibly unnecessary state change in `processDebtClaim()`", + "content": "##### Description\nThe `PoolBase.processDebtClaim()` function, which is called when an auction completes, has a line which sets the pool's state to `State.Default` (https://github.com/clearpool-finance/permissionless-protocol/blob/f1f38c5ba83e2c3a68155042229b04678d9425ce/contracts/pool/PoolBase.sol#L238):\n```solidity\n_info.state = State.Default;\n```\n\nHowever, if the pool were in a different state, we would not be able to start an auction in the first place, meaning that this function would not be called. Therefore, this line is unnecessary.\n\n\n##### Recommendation\n\nTo fix this issue, it is recommended to evaluate the conditions under which the `PoolBase.processDebtClaim()` function is called and determine whether the state change to `State.Default` is necessary. If it is not needed, the line of code should be removed to ensure that the state of the pool is not unnecessarily changed and that the function operates correctly.\n", + "protocol": "Clearpool", + "report_date": "2023-03-31", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/README.md#7-possibly-unnecessary-state-change-in-processdebtclaim", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/Clearpool%20Security%20Audit%20Report.pdf" + }, + { + "title": "Reentrancy Vulnerability in `bid()`", + "content": "##### Description\n\nAn attacker who is able to bypass the whitelist and register a pool with an ERC-777 token or a poisoned custom token may be able to exploit the reentrancy vulnerability in the `Auction.bid()` function. This would allow them to drain more funds to their benefit than intended by the contract's logic.\n\nThe attacker could potentially bypass the whitelist through social engineering or other means.\n\n- https://github.com/clearpool-finance/permissionless-protocol/blob/f1f38c5ba83e2c3a68155042229b04678d9425ce/contracts/Auction.sol#L121\n\n##### Recommendation\n\nIn order to fix this vulnerability, it is recommended to use the `nonReentrant` modifier from the OpenZeppelin's `ReentrancyGuard` contract in the `Auction.bid()` function. It is also recommended to add the `nonReentrant` modifier to the `Auction.resolveAuction()` function, just to be on the safe side. This will prevent these functions from being called recursively and will protect against reentrancy attacks.\n", + "protocol": "Clearpool", + "report_date": "2023-03-31", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/README.md#8-reentrancy-vulnerability-in-bid", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/Clearpool%20Security%20Audit%20Report.pdf" + }, + { + "title": "Out-of-gas vulnerability in `closePool()`", + "content": "##### Description\nThe [`closePool()`](https://github.com/clearpool-finance/permissionless-protocol/blob/f1f38c5ba83e2c3a68155042229b04678d9425ce/contracts/PoolFactory.sol#L402) function has a loop over both `pools.length` and `marketPools[market].length`. If these arrays become large enough, the function will stop working and will always return an out-of-gas error.\n\n##### Recommendation\n\nThere are different approaches to solve the problem. One option is to restrict the maximum number of pools that can be added. Another option is to use only mappings instead of arrays.\n", + "protocol": "Clearpool", + "report_date": "2023-03-31", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/README.md#9-out-of-gas-vulnerability-in-closepool", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/Clearpool%20Security%20Audit%20Report.pdf" + }, + { + "title": "`PoolFactory.closePool` doesn't reset `stakedAmount`", + "content": "##### Description\n\nIn `closePool`:\n- https://github.com/clearpool-finance/permissionless-protocol/blob/f1f38c5ba83e2c3a68155042229b04678d9425ce/contracts/PoolFactory.sol#L427\n\nafter unstaking `stakedAmount` won't be reset.\n\n##### Recommendation\n\nAlthough `closePool` calls once, we recommended setting `stakedAmount` as zero:\n```\ninfo.staker = address(0);\ninfo.stakedAmount = 0;\n```\n", + "protocol": "Clearpool", + "report_date": "2023-03-31", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/README.md#10-poolfactoryclosepool-doesnt-reset-stakedamount", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/Clearpool%20Security%20Audit%20Report.pdf" + }, + { + "title": "Parameters are not validated in `setPoolAuctionEnd`", + "content": "##### Description\n\n`setPoolAuctionEnd()` can be used by the owner to endlessly extend the auction or to finish it at any moment, for instance, after a particular bid.\n\n- https://github.com/clearpool-finance/permissionless-protocol/blob/68820cb61c8e3fa1714be0aca161d9916c8ac9d3/contracts/Auction.sol#L396\n\n##### Recommendation\nIt is recommended to add an upper limit for the auction time and forbid decreasing the auction length.\n\n", + "protocol": "Clearpool", + "report_date": "2023-03-31", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/README.md#11-parameters-are-not-validated-in-setpoolauctionend", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/Clearpool%20Security%20Audit%20Report.pdf" + }, + { + "title": "The `amount` parameter is not validated in `increaseBid(address pool, uint256 amount)`", + "content": "##### Description\n\nThe `increaseBid(address pool, uint256 amount)` function doesn't validate `amount`, zero amount can be passed to the function.\n\n##### Recommendation\nWe recommend adding:\n\n```\nrequire(amount > 0, \"\");\n```\n", + "protocol": "Clearpool", + "report_date": "2023-03-31", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/README.md#12-the-amount-parameter-is-not-validated-in-increasebidaddress-pool-uint256-amount", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Clearpool/Clearpool%20Security%20Audit%20Report.pdf" + }, + { + "title": "Incorrect blacklisting of unsafe calls", + "content": "##### Description\nAccording to the current design, the users of `Rubic` perform the ERC20 `approve` to the `ERC20Proxy` contract, allowing the ERC20 [tokens to be spent without further confirmations](https://github.com/Cryptorubic/multi-proxy-rubic/blob/8843336c50ca43e5b5bbe970f17e284f63a96763/src/Periphery/ERC20Proxy.sol#L40). It is crucially important to disallow any unauthorized calls to this contract, otherwise the user's ERC20 tokens may be spent by an unauthorized party.\n\nThe `LibSwap` library implements mechanics to perform an arbitrary call to an arbitrary address. By design, calls to `ERC20Proxy` are [blacklisted](https://github.com/Cryptorubic/multi-proxy-rubic/blob/8843336c50ca43e5b5bbe970f17e284f63a96763/src/Libraries/LibSwap.sol#L32). However, the blacklisting is set up in the context of `RubicMultiProxy` and will not work in the context of `Executor`, which is also granted a permission to call `ERC20Proxy` for [`_processSwaps`](https://github.com/Cryptorubic/multi-proxy-rubic/blob/8843336c50ca43e5b5bbe970f17e284f63a96763/src/Periphery/Executor.sol#L174). Therefore, an attacker can force `Executor` to call `ERC20Proxy` (see the Critical.2 finding), perform an unauthorized `transferFrom` and withdraw the ERC20 tokens of any user who gave an ERC20 `approve` to the `Rubic`.\n\n##### Recommendation\nIt is recommended to use more fail-safe practices of managing the ERC20 `approve` as described below in the recommendation for the Medium.1 finding. Additionally, it is advised to fix the blacklist issue for the `LibSwap`.\n\n\n", + "protocol": "Rubic", + "report_date": "2023-03-30", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Rubic/README.md#1-incorrect-blacklisting-of-unsafe-calls", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Rubic/Rubic%20Security%20Audit%20Report.pdf" + }, + { + "title": "Arbitrary calls execution in `Executor` and `GenericCrossChainFacet`", + "content": "##### Description\nThe `Executor` contract allows the execution of arbitrary calls in the shared context using the `stargate` functionality or directly by calling the [`swapAndExecute`](https://github.com/Cryptorubic/multi-proxy-rubic/blob/8843336c50ca43e5b5bbe970f17e284f63a96763/src/Periphery/Executor.sol#L114) external function.\n\n`GenericCrossChainFacet` also allows the execution of arbitrary calls in the shared context using the [swapAndStartBridgeTokensViaGenericCrossChain](https://github.com/Cryptorubic/multi-proxy-rubic/blob/ba18b51508c17f8dde2b1557bcbc58d48042ce6c/src/Facets/GenericCrossChainFacet.sol#L90). \n\nIt allows an attacker to setup ERC777 hooks, to provoke blacklisting and do something harmful to the `Executor` and the `Diamond` operationality.\n\nExecuting any external calls in the context of the vulnerable contract (`Executor` or `Diamond`) allows an attacker to intercept a transaction of another user and steal ERC777 tokens:\n1. Give an approve to the attacker contract from vulnerable contract for a ERC777 token. \n2. Set a `transferOnReceive` callback that executes the attacker contract after each transfer to the`Executor` or `Diamond` contract.\n3. Some user executes a swap that utilizes the ERC777 token in the end.\n4. The attacker contract using the approve (at step 1) drains the vulnerable contract inside the ERC777 callback implementation function.\n\n##### Recommendation\nIt is recommended to allow list calls from `Executor` similar to implementation at the facet part of the project. Additionaly, it is recommended to allow list bridges in the `GenericCrossChainFacet`.\n\n\n", + "protocol": "Rubic", + "report_date": "2023-03-30", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Rubic/README.md#2-arbitrary-calls-execution-in-executor-and-genericcrosschainfacet", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Rubic/Rubic%20Security%20Audit%20Report.pdf" + }, + { + "title": "Unsafe practice of managing a user's ERC20 approve", + "content": "##### Description\nAs it is stated above in the description of the Critical.1 finding, a user's ERC20 tokens can be spent without the user's confirmation. This bad practice reduces the overall project's security by amplifying the impact of other issues. For example, Critical.1 would have a Low severity, and the Medium.2 would be a no issue, if finding Medium.1 is fixed as recommended.\n\nAs a general architecture recommendation, this finding is described as a separate item of the report.\n##### Recommendation\nIt is recommended that every single spending of the user's ERC20 tokens be explicitly signed by the user.\n\n", + "protocol": "Rubic", + "report_date": "2023-03-30", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Rubic/README.md#1-unsafe-practice-of-managing-a-users-erc20-approve", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Rubic/Rubic%20Security%20Audit%20Report.pdf" + }, + { + "title": "The administrator can modify trusted functionality", + "content": "##### Description\nThe `DiamondCutFacet` allows the `Owner` to [add a new facet with unaudited code](https://github.com/Cryptorubic/multi-proxy-rubic/blob/8843336c50ca43e5b5bbe970f17e284f63a96763/src/Libraries/LibDiamond.sol#L93). In combination with the Medium.1 finding, it may lead to users' wallets being drained. Additionaly, the `Owner` is allowed to [add a brand new smart contract](https://github.com/Cryptorubic/multi-proxy-rubic/blob/8843336c50ca43e5b5bbe970f17e284f63a96763/src/Periphery/ERC20Proxy.sol#L27) to the list of trusted contracts.\n##### Recommendation\nIt is recommended to resolve the Medium.1 finding in order to minimize the impact of the `Owner`'s actions.\n\n", + "protocol": "Rubic", + "report_date": "2023-03-30", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Rubic/README.md#2-the-administrator-can-modify-trusted-functionality", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Rubic/Rubic%20Security%20Audit%20Report.pdf" + }, + { + "title": "Unused logic", + "content": "##### Description\nModifiers [`noLeftovers`](https://github.com/Cryptorubic/multi-proxy-rubic/blob/8843336c50ca43e5b5bbe970f17e284f63a96763/src/Helpers/SwapperV2.sol#L31) and [`refundExcessNavtive`](https://github.com/Cryptorubic/multi-proxy-rubic/blob/8843336c50ca43e5b5bbe970f17e284f63a96763/src/Helpers/SwapperV2.sol#L115) use balances differences before and after swaps to calculate leftovers but no any token is supposed to be on the balance before a swap. That's why using just balances is more efficient and simple.\n##### Recommendation\nIt is recommended to simplify modifiers and use just balances.\n\n", + "protocol": "Rubic", + "report_date": "2023-03-30", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Rubic/README.md#1-unused-logic", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Rubic/Rubic%20Security%20Audit%20Report.pdf" + }, + { + "title": "Bypassing payment fees through various methods", + "content": "##### Description\n\nSwapExecutor, a contract responsible for executing token swaps, is vulnerable to multiple methods of bypassing payment fees, allowing an attacker to perform swaps without paying the required fees.\n\nThe first method involves specifying a personal transfer of all tokens in the final swap, leaving only 2 wei of `tokenToTransfer` on the contract to avoid paying fees. This enables the attacker to evade payment and execute swaps at no cost.\n\n- https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/SwapExecutor.sol#L146\n\nThe second method involves passing a swap-path that ends with a poisonous token created by the attacker. The attacker pays fees in their own token, which is worthless, thus bypassing payment fees.\n\n- https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/SwapFacade.sol#L35\n\nThe third method involves copying the code of SwapExecutor and removing the payment logic, allowing the attacker to continue using the SwapFacade without paying any fees by passing the custom SwapExecutor to `SwapFacade.swap()`.\n\n- https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/SwapFacade.sol#L29\n\nOverall, these vulnerabilities allow attackers to perform swaps without paying the required fees, leading to potential financial losses for the SwapExecutor owners.\n\n##### Recommendation\n\nOne way to address the vulnerabilities in SwapExecutor is to take a fixed fee in a fixed token, such as Ether, in SwapFacade.\n", + "protocol": "Barter DAO", + "report_date": "2023-03-15", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/README.md#1-bypassing-payment-fees-through-various-methods", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/Barter%20DAO%20Security%20Audit%20Report.pdf" + }, + { + "title": "Hashflow RFQ-integration", + "content": "##### Description\n\nSince we receive `HashflowQuote` before the call occurred, the information at the time of the transaction may not be up to date. \n\nIn that case, due to this code:\n\n```\nif (amount > quote.maxBaseTokenAmount) {\n emit AmountExceedsQuote(amount, quote.maxBaseTokenAmount);\n quote.effectiveBaseTokenAmount = quote.maxBaseTokenAmount;\n} else {\n quote.effectiveBaseTokenAmount = amount;\n}\n```\n\npart of the money may remain with the `SwapExecutor`.\n\n- https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/helpers/HashflowHelper.sol#L24\n\n##### Recommendation\n\nWe recommend adding a revert if the input `amount` is not actual.\n", + "protocol": "Barter DAO", + "report_date": "2023-03-15", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/README.md#2-hashflow-rfq-integration", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/Barter%20DAO%20Security%20Audit%20Report.pdf" + }, + { + "title": "Swaps through an ERC777 token can lead to DoS of these swaps", + "content": "##### Description\n\nERC777 tokens allow hooks before and after balance changes.\nTransfer `_from` and `to` can choose the exact receivers of these hooks via `Registry.setInterfaceImplementer()`:\n- [ERC1820Registry](https://etherscan.io/address/0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24)\n\nAlso, Executor allows anyone to call `executeSwap()` and decide on the following targets and calldata.\n\n1) An attacker uses `executeSwap()` so that Executor calls `ERC1820Registry.setInterfaceImplementer(implementer=attacker)`. \n2) User A swaps an ERC777 token to something with low `minReturn`. It must be at least one ERC777 among the list of tokens in swaps.\n3) Executor receives ERC777 tokens from Facade (hook).\n4) The attacker reverts on the hook.\n\nAs a result, any ERC777 token going through Executor will lead to DoS and swap will revert.\n\nSo, one of the attack flows can be like this:\n1) Attacker uses `executeSwap()` so that Executor calls `ERC1820Registry.setInterfaceImplementer(implementer=attacker)'. \nSo, anytime Executor receives ERC777 tokens, a frontrunner contract will be called.\n2) User A swaps the ERC777 tokens to something with low `minReturn`.\n3) Executor receives the ERC777 tokens from Facade (hook).\n4) Attacker contract enters Executor.executeSwap() and Executor thinks that current ERC777 tokens belong to Attacker. So, he can withdraw these tokens, or swap them to something.\n\nOr at least Attacker can revert when recieving a call, not allowing a swap with this token at all.\n\n##### Recommendation\n\nWe recommend that Facade be the only allowed caller for `SwapExecutor.execureSwap()` with the Reentrancy guard and be sure that `minReturn` is set even for small swaps.\n", + "protocol": "Barter DAO", + "report_date": "2023-03-15", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/README.md#3-swaps-through-an-erc777-token-can-lead-to-dos-of-these-swaps", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/Barter%20DAO%20Security%20Audit%20Report.pdf" + }, + { + "title": "Facade allows any unauthorized Executor", + "content": "##### Description\n\nSwapFacade allows to choose any SwapExecutor address, even not authored by the team. Fees are charged on SwapExecutor. So, it is rational to fork SwapExecutor with zero fees and choose it as an executor for swaps.\n\n- https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/SwapFacade.sol#L87\n\nSome other possible scenarios:\n- users can choose out date executors\n- users can choose executors with bugs\n\n##### Recommendation\nWe recommend having a list of allowed executors and taking fees on SwapFacade.\n", + "protocol": "Barter DAO", + "report_date": "2023-03-15", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/README.md#1-facade-allows-any-unauthorized-executor", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/Barter%20DAO%20Security%20Audit%20Report.pdf" + }, + { + "title": "Anyone can withdraw funds left on `SwapExecutor`", + "content": "##### Description\n\nFunds left on the `SwapExecutor` can be withdrawn by anyone who specifies a transfer call in the swaps.\n\nThere are multiple reasons why funds may be left on the `SwapExecutor`:\n1. A user may not set the `tokenRatio` to 100% in a swap.\n\n```\nuint256 poolSwapAmount = (balanceToSwap * swap.tokenRatio) / _ONE;\n\n# sum (tokenRatio) > _ONE - is not risky, revert happens\n# sum (tokenRatio) < _ONE - is risky, as some tokens \n are left not swapped and can be taken by anyone.\n```\n\n2. The `SwapExecutor` may run arbitrary calls to protocols that reward it with additional tokens. The `SwapFacade` only checks the `tokenToTransfer`, and a user may forget to transfer other tokens from the `SwapExecutor` immediately.\n3. If a user transfers tokens to the `SwapExecutor` first and then runs the `SwapFacade.swap()` function in a separate transaction.\n\n- https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/SwapExecutor.sol#L58\n\n##### Recommendation\nTo address this, a similar approach to that used in CowProtocol could be implemented: allowing only whitelisted managers to execute swaps in SwapExecutor.\n\nIt is also recommended to check that all `tokenRatio` used eventually sum up to 100%. \n", + "protocol": "Barter DAO", + "report_date": "2023-03-15", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/README.md#2-anyone-can-withdraw-funds-left-on-swapexecutor", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/Barter%20DAO%20Security%20Audit%20Report.pdf" + }, + { + "title": "ETH value above limited value can be lost", + "content": "##### Description\n\nSwapExecutor has the following lines for ETH:\n\n```\nif (value > valueLimit) {\n value = valueLimit;\n}\n(success, result) = target.call{ value: value }(data);\n```\n\n- https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/SwapExecutor.sol#L116-L120\n\nSo, only a limited amount will be used if sent ETH is above valueLimit.\nThis ETH will be lost on the contract and anyone can withdraw these exceeded amounts.\n\n##### Recommendation\nWe recommend redesigning valueLimit purpose so that no funds are lost in edge situations.\n", + "protocol": "Barter DAO", + "report_date": "2023-03-15", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/README.md#3-eth-value-above-limited-value-can-be-lost", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/Barter%20DAO%20Security%20Audit%20Report.pdf" + }, + { + "title": "A swap with permit can be blocked if a frontrunner swaps using copied permit", + "content": "##### Description\n\nFacade does not check that msg.sender is the owner of a permit.\nSo, a frontrunner can use permits of other users available from mempool, so that their transactions would revert (as permit are used by the frontrunner).\n\n- https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/SwapFacade.sol#L58-L64\n\nA user will receive revert and will have to build new calldata, without permit.\n\n##### Recommendation\n\nWe recommend decoding permits to extract their owner, then check that msg.sender is this owner. Some example used by 1inch:\n- https://github.com/1inch/solidity-utils/blob/60fa6eba06f50f2acac5286dea5fb54f206e2434/contracts/libraries/SafeERC20.sol#L158-L245\n\n***", + "protocol": "Barter DAO", + "report_date": "2023-03-15", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/README.md#4-a-swap-with-permit-can-be-blocked-if-a-frontrunner-swaps-using-copied-permit", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/Barter%20DAO%20Security%20Audit%20Report.pdf" + }, + { + "title": "Unprotected access to `makeCheckpoint()` in SwapGuardV2", + "content": "##### Description\n\nSwapGuardV2 functions are planned to be used as separate calls in a set of swaps. However, if during the swaps process a hacker manages to get a callback to their own contract (for example, if the victim operates with ERC-777 tokens), the hacker can call public accessible function `makeCheckpoint()` to modify the SwapGuardV2 state so that the `ensureCheckpoint()` function at the victim's end would not work correctly.\n\nhttps://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/SwapGuardV2.sol#L20\n\n##### Recommendation\n\nIt is recommended to revise the approach to using SwapGuardV2. It may be reasonable to leave only one function in SwapGuardV2, which receives a set of tokens, deltas and a callback. The function records the current token balances in memory instead of a storage, then calls the user's callback (which performs swaps), and then checks for changes in the balances.\n", + "protocol": "Barter DAO", + "report_date": "2023-03-15", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/README.md#5-unprotected-access-to-makecheckpoint-in-swapguardv2", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/Barter%20DAO%20Security%20Audit%20Report.pdf" + }, + { + "title": "`Ownable` can be upgraded to `Ownable2Step`", + "content": "##### Description\n\nSwapExecutor uses the `Ownable` functionality:\n\nhttps://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/SwapExecutor.sol#L24\n\nThe `Ownable` contract can be upgraded to Open Zeppelin's `Ownable2Step`:\nhttps://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable2Step.sol\n\n`Ownable2Step` provides added safety due to its securely designed two-step process.\n\n\n##### Recommendation\n\nWe recommend applying `Ownable2Step` instead of `Ownable`.\n\n\n***\n", + "protocol": "Barter DAO", + "report_date": "2023-03-15", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/README.md#1-ownable-can-be-upgraded-to-ownable2step", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/Barter%20DAO%20Security%20Audit%20Report.pdf" + }, + { + "title": "Simplifying `setFeeAndFeeRecipient()` logic for gas optimization", + "content": "##### Description\n\nThe current implementation manually packs and unpacks the fee and address from a uint256 value, which increases the likelihood of errors and may cause unnecessary gas usage.\n\n* https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/SwapExecutor.sol#L48\n* https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/SwapExecutor.sol#L137\n\n##### Recommendation\n\nTo simplify the logic and optimize gas usage, it's recommended to store the fee and address separately in the contract's state using two separate variables:\n```soliditiy\nuint160 feeAddress;\nuint96 fee;\n```\n\nBoth variables will fit into a single storage slot. This will also allow more efficient retrieval of the fee-related data.\n\n***\n", + "protocol": "Barter DAO", + "report_date": "2023-03-15", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/README.md#2-simplifying-setfeeandfeerecipient-logic-for-gas-optimization", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/Barter%20DAO%20Security%20Audit%20Report.pdf" + }, + { + "title": "Missing zero-checks", + "content": "##### Description\n\nThere are no zero checks for `recipient` and `minReturn`:\n* https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/SwapFacade.sol#L32\n* https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/SwapFacade.sol#L33\n\nSome programs may pass zero values for some arguments by default. A user may not notice this behaviour and lose funds.\n\n##### Recommendation\n\nIt is recommended to add requirements which check that the `recipient` and `minReturn` are not zero.\n\n***\n", + "protocol": "Barter DAO", + "report_date": "2023-03-15", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/README.md#3-missing-zero-checks", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/Barter%20DAO%20Security%20Audit%20Report.pdf" + }, + { + "title": "SwapGuardV2 has multiple problems", + "content": "##### Description\n\n1. Contracts that use SwapGuardV2 together with Facade+Executor are out of scope\n2. All functions are public and anyone can makeCheckpoint()\n3. This contract will not work with native ETH.\n4. allowedLoss adds up with tokens having different decimals. Or tokensPrices must at least include decimals\n5. Lengths of tokens, tokenPrices and balanceChanges are not checked to be the same\n6. All checkpoints are written to storage, no need if it is used in one transaction\n\n- https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/SwapGuardV2.sol#L20-L58\n\n##### Recommendation\n\nWe recommend using more efficient ways to check profitability of swaps.\n", + "protocol": "Barter DAO", + "report_date": "2023-03-15", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/README.md#4-swapguardv2-has-multiple-problems", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/Barter%20DAO%20Security%20Audit%20Report.pdf" + }, + { + "title": "Protection against accidential ETH sendings does not work", + "content": "##### Description\n\nBoth Facade and Executor inherit ContractOnlyEthRecipient.sol with the following code.\n\n```\n/**\n * @title ContractOnlyEthRecipient\n * @notice Base contract that rejects any direct ethereum deposits. \n This is a failsafe against users who can accidentaly send ether\n */\nabstract contract ContractOnlyEthRecipient {\n receive() external payable {\n // solhint-disable-next-line avoid-tx-origin\n if (msg.sender == tx.origin) {\n revert DirectEthDepositIsForbidden();\n }\n }\n}\n```\n\nIn fact, only Executor needs this inheritance, as it can receive ETH from external exchanges.\nBut Facade should only receive ETH as msg.value at swap().\n\nAlso, in the comments developers stated that it is against accidential ETH sendings.\nBy the way, it still allows to receive accidential ETH from users as contracts (like user wallets). Moreover, any accidential ETH on balances are bad (can be stolen), so it is better to remove options to receive accidential money when it\u2019s possible.\n\n##### Recommendation\n\nWe recommend removing `recieve()` for `SwapFacade` and `SwapGuardV2`.\n\n***\n", + "protocol": "Barter DAO", + "report_date": "2023-03-15", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/README.md#5-protection-against-accidential-eth-sendings-does-not-work", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/Barter%20DAO%20Security%20Audit%20Report.pdf" + }, + { + "title": "Not effective depositETH() and withdrawETH()", + "content": "##### Description\n\n`depositETH()` and `withdrawETH()` are inherited and make calls to WETH.\n\nIt is used to swap between native ETH and WETH. But the implementation makes Executor call itself (external call), send ETH itself.\n\nThis step is useless and can be dropped.\n\n```\nfunction depositWeth(uint256 amount) external payable {\n if (amount != msg.value) {\n revert EthValueAmountMismatch();\n }\n weth.deposit{value: amount}();\n}\n\nfunction withdrawWeth(uint256 amount) external {\n weth.withdraw(amount);\n}\n```\n\n##### Recommendation\n\nWe recommend removing these functions and use WETH as target directly.\n\n***\n", + "protocol": "Barter DAO", + "report_date": "2023-03-15", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/README.md#6-not-effective-depositeth-and-withdraweth", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/Barter%20DAO%20Security%20Audit%20Report.pdf" + }, + { + "title": "Use `encodeCall`", + "content": "##### Description\n\n`abi.encodeCall` is a safer way to avoid mistakes during compilation. The compiler checks that the types of args are compatible with a call.\n\n- https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/helpers/UniswapV2Helper.sol#L31\n- https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/helpers/HashflowHelper.sol#L30\n- https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/helpers/DssPsmHelper.sol#L31\n- https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/helpers/DodoV1Helper.sol#L22\n\n##### Recommendation\n\nWe recommend changing `encodeWithSelector` to `encodeCall`.\n\n***\n", + "protocol": "Barter DAO", + "report_date": "2023-03-15", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/README.md#7-use-encodecall", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/Barter%20DAO%20Security%20Audit%20Report.pdf" + }, + { + "title": "Missing caller verification in `uniswapV3SwapCallback()`", + "content": "##### Description\n\nThe `uniswapV3SwapCallback()` function in the `IUniswapV3SwapCallback` interface, which is part of the Uniswap v3 protocol, is used to handle the results of a swap. However, the function in `UniswapV3Executor` does not include any caller verification, which can lead to potential vulnerabilities.\n\n- https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/features/UniswapV3Executor.sol#L20\n\n##### Recommendation\n\nThe uniswap team recommends checking that the caller of the `uniswapV3SwapCallback()` is a `UniswapV3Pool` deployed by the canonical `UniswapV3Factory`:\n- https://github.com/Uniswap/v3-core/blob/main/contracts/interfaces/callback/IUniswapV3SwapCallback.sol\n\nNote that this increases the amount of gas used.\n\n\n***\n", + "protocol": "Barter DAO", + "report_date": "2023-03-15", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/README.md#8-missing-caller-verification-in-uniswapv3swapcallback", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/Barter%20DAO%20Security%20Audit%20Report.pdf" + }, + { + "title": "Funds stuck in `SwapFacade` cannot be withdrawn", + "content": "##### Description\n\nERC-20 token funds cannot be withdrawn from SwapFacade if a user accidentally sends tokens to the SwapFacade contract instead of SwapExecutor.\n\n- https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/SwapFacade.sol#L16\n\n##### Recommendation\n\nIt is recommended to add a `sweep(token) onlyOwner` function with the onlyOwner modifier. This function will allow the owner of the contract to sweep any funds that are stuck in the contract and transfer them to a designated account. This will provide a safety net for users who accidentally send funds to the contract, preventing their funds from being lost or stolen.\n\n***\n", + "protocol": "Barter DAO", + "report_date": "2023-03-15", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/README.md#9-funds-stuck-in-swapfacade-cannot-be-withdrawn", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/Barter%20DAO%20Security%20Audit%20Report.pdf" + }, + { + "title": "A potential overflow due to unsafe math", + "content": "##### Description\nIn `SwapExecutor` this line `uint256 poolSwapAmount = (balanceToSwap * swap.tokenRatio) / _ONE` allows making overflow.\n\nExample (https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/SwapExecutor.sol#L73):\n```\nuint256 poolSwapAmount = (balanceToSwap * swap.tokenRatio) / _ONE;\n```\n\n##### Recommendation\n\nWe recommend removing unsafe math from critical functions.\n", + "protocol": "Barter DAO", + "report_date": "2023-03-15", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/README.md#10-a-potential-overflow-due-to-unsafe-math", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/Barter%20DAO%20Security%20Audit%20Report.pdf" + }, + { + "title": "Use `UniswapV2Router02` to avoid duplication of code", + "content": "##### Description\n\n`UniswapV2Helper` duplicates the existing code of `UniswapV2Router` from the official Uniswap repo.\n\n- https://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/helpers/UniswapV2Helper.sol#L18\n\n##### Recommendation\n\nWe recommend using the existing functionality to avoid potential mistakes.\n", + "protocol": "Barter DAO", + "report_date": "2023-03-15", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/README.md#11-use-uniswapv2router02-to-avoid-duplication-of-code", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/Barter%20DAO%20Security%20Audit%20Report.pdf" + }, + { + "title": "`SwapFacade.swap()` gas optimisations", + "content": "##### Description\n\nThe logic in `SwapFacade.swap()` can be simplified to always call the `_permit()`.\n\nThe logic at lines 59-73\nhttps://github.com/BarterLab/argon/blob/22239aaccdbb78d4aa7ac5c4d0859a9b31c0fc00/contracts/SwapFacade.sol#L63\n```solidity\n uint256 currentBalance = sourceToken.balanceOf(address(executor));\nif (currentBalance < amount)\n{\n if (permit.length > 0) {\n _permit(address(sourceToken), permit);\n }\n uint256 approveAmount = sourceToken.allowance(\n msg.sender,\n address(this)\n );\n if (approveAmount < amount) {\n revert NotEnoughApprovedFundsForSwap(approveAmount, amount);\n }\n sourceToken.safeTransferFrom(msg.sender, address(executor), amount);\n}\n```\n\ncan be simplified down to just two lines (always call `_permit()`):\n\n```solidity\n_permit(address(sourceToken), permit);\nsourceToken.safeTransferFrom(msg.sender, address(executor), amount);\n```\n\nNote that the 1inch `_permit()` is already checking `permit.length` and does nothing in case it is zero:\n```solidity\ncontract Permitable {\n error BadPermitLength();\n\n function _permit(address token, bytes calldata permit) \n internal virtual {\n if (permit.length > 0) {\n bool success;\n if (permit.length == 32 * 7) {\n // solhint-disable-next-line avoid-low-level-calls\n (success,) = token.call(\n abi.encodePacked(IERC20Permit.permit.selector, permit)\n );\n } else if (permit.length == 32 * 8) {\n // solhint-disable-next-line avoid-low-level-calls\n (success,) = token.call(\n abi.encodePacked(IDaiLikePermit.permit.selector, permit)\n );\n } else {\n revert BadPermitLength();\n }\n if (!success) {\n RevertReasonForwarder.reRevert();\n }\n }\n }\n}\n```\n\n##### Recommendation\n\nIt is recommended to remove unnecessary conditions to save gas.\n\n***\n\n", + "protocol": "Barter DAO", + "report_date": "2023-03-15", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/README.md#12-swapfacadeswap-gas-optimisations", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Barter%20DAO/Barter%20DAO/Barter%20DAO%20Security%20Audit%20Report.pdf" + }, + { + "title": "Destruction of the EnsoWallet implementation contract", + "content": "##### Description\nAn attacker can make a direct call (not via proxy) to [EnsoWallet.initialize()](https://github.com/EnsoFinance/shortcuts-contracts/blob/4902e55608f975f73772310955444110b1cfc4fc/contracts/EnsoWallet.sol#L24) and execute the SELFDESTRUCT opcode or specify themself as EXECUTOR and gain the ability to execute SELFDESTRUCT later. Consequently, the current implementation contract will be destroyed, and all users' wallet functionality will be inaccessible until the core upgrade. The worst case occurs if an attack happens after EnsoBeacon.renounceAdministration(), and all users' funds will be frozen.\n##### Recommendation\nWe recommend disallowing direct calls to EnsoWallet.initialize().\n\n\n", + "protocol": "Enso Finance", + "report_date": "2023-02-21", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Enso%20Finance/Enso%20Wallet/README.md#1-destruction-of-the-ensowallet-implementation-contract", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Enso%20Finance/Enso%20Wallet/Enso%20Wallet%20Security%20Audit%20Report.pdf" + }, + { + "title": "Front-run attack on the deployment of EnsoWalletFactory", + "content": "##### Description\nAn attacker can place their transactions between the deployment of the EnsoWalletFactory implementation and [EnsoWalletFactory.initialize()](https://github.com/EnsoFinance/shortcuts-contracts/blob/4902e55608f975f73772310955444110b1cfc4fc/contracts/EnsoWalletFactory.sol#L26) to specify themself as the contract owner and make an upgrade of the EnsoWalletFactory to the modified one. The modified factory contract may implement backdoor functionality to gain control of the deployed user wallets.\n\n##### Recommendation\nWe recommend improving the code of the upgradeable proxy to disallow the gain of ownership by arbitrary accounts or at least improve the deployment process in order to implement deployment and initialization in a single transaction.\n\n\n", + "protocol": "Enso Finance", + "report_date": "2023-02-21", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Enso%20Finance/Enso%20Wallet/README.md#2-front-run-attack-on-the-deployment-of-ensowalletfactory", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Enso%20Finance/Enso%20Wallet/Enso%20Wallet%20Security%20Audit%20Report.pdf" + }, + { + "title": "EXECUTOR has a full write access to the wallet storage", + "content": "##### Description\nEXECUTOR has a write access to any storage slots vie the executeShortcut function and delegatecall to a specially crafted library. This allows to trigger\ntransfer/renounce of the OWNER address and other unintended actions.\nhttps://github.com/EnsoFinance/shortcuts-contracts/blob/4902e55608f975f73772310955444110b1cfc4fc/contracts/EnsoWallet.sol#L57\n##### Recommendation\nWe recommend implementing an access control for the DELEGATECALL, i.e. a whitelist of permitted libraries.\n\n\n", + "protocol": "Enso Finance", + "report_date": "2023-02-21", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Enso%20Finance/Enso%20Wallet/README.md#1-executor-has-a-full-write-access-to-the-wallet-storage", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Enso%20Finance/Enso%20Wallet/Enso%20Wallet%20Security%20Audit%20Report.pdf" + }, + { + "title": "Admin can bypass the upgrade delay by `setDelay`", + "content": "##### Description\nThe contract implements a special flow to upgrade the wallet core with delay, but the admin can force an immediate upgrade by reducing the delay using setDelay().\nhttps://github.com/EnsoFinance/shortcuts-contracts/blob/4902e55608f975f73772310955444110b1cfc4fc/contracts/EnsoBeacon.sol#L208\n\nThis will deprive users of the ability to check implementations before applying.\n\n##### Recommendation\nWe recommend improving the upgrade delay flow.\n\n\n", + "protocol": "Enso Finance", + "report_date": "2023-02-21", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Enso%20Finance/Enso%20Wallet/README.md#2-admin-can-bypass-the-upgrade-delay-by-setdelay", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Enso%20Finance/Enso%20Wallet/Enso%20Wallet%20Security%20Audit%20Report.pdf" + }, + { + "title": "Admin can bypass the upgrade delay by `delegate` and `emergencyUpgrade`", + "content": "##### Description\nThe admin can bypass the upgrade delay flow and immediately change the address of the wallet core by following the sequence:\n- `transferDelegation` (to a new `delegate` account, controlled by the admin)\n- `acceptDelegation` (from the `delegate` account)\n- `upgradeFallback` (from the admin account)\n- `emegrencyUpgrade` (from the `delegate` account)\n##### Recommendation\nWe recommend improving the upgrade delay flow.\n\n\n", + "protocol": "Enso Finance", + "report_date": "2023-02-21", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Enso%20Finance/Enso%20Wallet/README.md#3-admin-can-bypass-the-upgrade-delay-by-delegate-and-emergencyupgrade", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Enso%20Finance/Enso%20Wallet/Enso%20Wallet%20Security%20Audit%20Report.pdf" + }, + { + "title": "Conflicting flow of pending `upgradeFactory` and `setFactory`", + "content": "##### Description\nCalling [`finalizeUpgrade`](https://github.com/EnsoFinance/shortcuts-contracts/blob/4902e55608f975f73772310955444110b1cfc4fc/contracts/EnsoBeacon.sol#L74) after `setFactory` can cause unexpected behavior.\n##### Recommendation\nWe recommend improving the upgrade delayflow.\n\n\n", + "protocol": "Enso Finance", + "report_date": "2023-02-21", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Enso%20Finance/Enso%20Wallet/README.md#1-conflicting-flow-of-pending-upgradefactory-and-setfactory", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Enso%20Finance/Enso%20Wallet/Enso%20Wallet%20Security%20Audit%20Report.pdf" + }, + { + "title": "Insufficient event emitting", + "content": "##### Description\nIn some edge cases it may be not so easy to obtain the wallet owner address and address of the factory that created it.\n##### Recommendation\nWe recommend adding the wallet owner and the factory address to the [`Deployed` event](https://github.com/EnsoFinance/shortcuts-contracts/blob/4902e55608f975f73772310955444110b1cfc4fc/contracts/EnsoWalletFactory.sol#L90).\n\n\n", + "protocol": "Enso Finance", + "report_date": "2023-02-21", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Enso%20Finance/Enso%20Wallet/README.md#2-insufficient-event-emitting", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Enso%20Finance/Enso%20Wallet/Enso%20Wallet%20Security%20Audit%20Report.pdf" + }, + { + "title": "Potential hash collisions for constants", + "content": "##### Description\n[The constants for the access roles `OWNER_ROLE` and `EXECUTOR_ROLE`](https://github.com/EnsoFinance/shortcuts-contracts/blob/4902e55608f975f73772310955444110b1cfc4fc/contracts/access/Roles.sol#L5)\nare vulnerable to potential hash collisions.\n##### Recommendation\nAlthough, we currently can't find any attack vector for this issue, we recommend improving the security of the constants by decreasing it by `-1` just like it is [implemented here](https://github.com/EnsoFinance/shortcuts-contracts/blob/4902e55608f975f73772310955444110b1cfc4fc/contracts/access/Ownable.sol#L11).\n\n\n", + "protocol": "Enso Finance", + "report_date": "2023-02-21", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Enso%20Finance/Enso%20Wallet/README.md#3-potential-hash-collisions-for-constants", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Enso%20Finance/Enso%20Wallet/Enso%20Wallet%20Security%20Audit%20Report.pdf" + }, + { + "title": "Null checks", + "content": "##### Description\nSome parameters have no null checks:\n- https://github.com/EnsoFinance/shortcuts-contracts/blob/4902e55608f975f73772310955444110b1cfc4fc/contracts/EnsoBeacon.sol#L201\n- https://github.com/EnsoFinance/shortcuts-contracts/blob/4902e55608f975f73772310955444110b1cfc4fc/contracts/EnsoBeacon.sol#L123\n- https://github.com/EnsoFinance/shortcuts-contracts/blob/4902e55608f975f73772310955444110b1cfc4fc/contracts/access/AccessController.sol#L21\n##### Recommendation\nWe recommend adding a null check for `newFactory`, `newImplementation` and `account`.\n\n\n", + "protocol": "Enso Finance", + "report_date": "2023-02-21", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Enso%20Finance/Enso%20Wallet/README.md#4-null-checks", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Enso%20Finance/Enso%20Wallet/Enso%20Wallet%20Security%20Audit%20Report.pdf" + }, + { + "title": "Using ```memory``` instead of ```calldata```", + "content": "##### Description\nUsing ```memory``` instead of ```calldata``` for input arrays in external functions:\nhttps://github.com/EnsoFinance/shortcuts-contracts/blob/4902e55608f975f73772310955444110b1cfc4fc/contracts/wallet/MinimalWallet.sol#L45\nhttps://github.com/EnsoFinance/shortcuts-contracts/blob/4902e55608f975f73772310955444110b1cfc4fc/contracts/wallet/MinimalWallet.sol#L84\nhttps://github.com/EnsoFinance/shortcuts-contracts/blob/4902e55608f975f73772310955444110b1cfc4fc/contracts/wallet/MinimalWallet.sol#L101\nhttps://github.com/EnsoFinance/shortcuts-contracts/blob/4902e55608f975f73772310955444110b1cfc4fc/contracts/wallet/MinimalWallet.sol#L112\nhttps://github.com/EnsoFinance/shortcuts-contracts/blob/4902e55608f975f73772310955444110b1cfc4fc/contracts/wallet/MinimalWallet.sol#L121\nhttps://github.com/EnsoFinance/shortcuts-contracts/blob/4902e55608f975f73772310955444110b1cfc4fc/contracts/wallet/MinimalWallet.sol#L145\nhttps://github.com/EnsoFinance/shortcuts-contracts/blob/4902e55608f975f73772310955444110b1cfc4fc/contracts/wallet/MinimalWallet.sol#L155\nhttps://github.com/EnsoFinance/shortcuts-contracts/blob/4902e55608f975f73772310955444110b1cfc4fc/contracts/wallet/MinimalWallet.sol#L165\n##### Recommendation\nWe recommend replacing ```memory``` by ```calldata```.\n\n\n", + "protocol": "Enso Finance", + "report_date": "2023-02-21", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Enso%20Finance/Enso%20Wallet/README.md#5-using-memory-instead-of-calldata", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Enso%20Finance/Enso%20Wallet/Enso%20Wallet%20Security%20Audit%20Report.pdf" + }, + { + "title": "Spelling mistakes", + "content": "##### Description\nSome texts have spelling mistakes:\n1) `balanceAdderess` -> `balanceAddress`\n https://github.com/EnsoFinance/shortcuts-contracts/blob/4902e55608f975f73772310955444110b1cfc4fc/contracts/helpers/EnsoShortcutsHelpers.sol#L14\n2) `renounes` -> `renouns`\n https://github.com/EnsoFinance/shortcuts-contracts/blob/4902e55608f975f73772310955444110b1cfc4fc/contracts/EnsoBeacon.sol#L147\n3) `alway` -> `always`\n https://github.com/EnsoFinance/shortcuts-contracts/blob/4902e55608f975f73772310955444110b1cfc4fc/contracts/EnsoBeacon.sol#L179\n4) `indetify` -> `identify`\n https://github.com/EnsoFinance/shortcuts-contracts/blob/4902e55608f975f73772310955444110b1cfc4fc/contracts/EnsoWalletFactory.sol#L43\n https://github.com/EnsoFinance/shortcuts-contracts/blob/4902e55608f975f73772310955444110b1cfc4fc/contracts/EnsoWalletFactory.sol#L79\n5) `implemenation` -> `implementation`\n https://github.com/EnsoFinance/shortcuts-contracts/blob/4902e55608f975f73772310955444110b1cfc4fc/contracts/EnsoBeacon.sol#L67\n##### Recommendation\nWe recommend correcting the mistakes.\n\n\n", + "protocol": "Enso Finance", + "report_date": "2023-02-21", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Enso%20Finance/Enso%20Wallet/README.md#6-spelling-mistakes", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Enso%20Finance/Enso%20Wallet/Enso%20Wallet%20Security%20Audit%20Report.pdf" + }, + { + "title": "Unchecked timelock delay", + "content": "##### Description\nThe administrator can inadvertently (i.e. using millisecond timestamp notation) setup a timelock delay that is too long. This may cause an unacceptably long delay (i.e. a two-year delay instead of a seven-day delay).\n##### Recommendation\nWe recommend disallowing unintended long delays by limiting the maximum delay of the timelock with some reasonable value.\n\n\n", + "protocol": "Enso Finance", + "report_date": "2023-02-21", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Enso%20Finance/Enso%20Wallet/README.md#7-unchecked-timelock-delay", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Enso%20Finance/Enso%20Wallet/Enso%20Wallet%20Security%20Audit%20Report.pdf" + }, + { + "title": "Passing the `return data` by the EVM state", + "content": "##### Description\n[`execTransactionFromModuleReturnData`](https://github.com/EnsoFinance/shortcuts-contracts/blob/951a4a247165f4209bceb6deb628a4970bf3f6da/contracts/wallet/ModuleManager.sol#L45) is using `returndatasize` and `returndatacopy` in the assumption that virtual function `_executeCall` is preserving the result of the corresponding external call at the EVM state. As for the audited commit, this assumption is correct. However, the implementation of the virtual `_executeCall` function may become more complex during a past codebase development, and this assumption may break the contract logic later.\n##### Recommendation\nIt is recommended to avoid using the EVM state as a method of passing values outside of a single solidity function, especially if the values are passed between functions located in different source files.\n\n\n", + "protocol": "Enso Finance", + "report_date": "2023-02-21", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Enso%20Finance/Enso%20Wallet/README.md#8-passing-the-return-data-by-the-evm-state", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Enso%20Finance/Enso%20Wallet/Enso%20Wallet%20Security%20Audit%20Report.pdf" + }, + { + "title": "Contract works with non-existent collections and tokens", + "content": "##### Description\n1. View methods (`getRoyalties()`, `tokenURI()`) work with non-existent collections.\n\nIn this example, incorrect royalty is returned for a non-existent collection:\n```\nawait nftContract.getRoyalties(0);\n# returns:\nrecipients: [\n '0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC',\n '0x0000000000000000000000000000000000000000'\n]\nbps: [\n BigNumber { value: \"250\" }, \n BigNumber { value: \"0\" }\n]\n```\n\n2. Athletes and Platform Manager can change parameters for non-existent collections. For example, function `updateCollectionAthleteAddress` (https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L308).\n\n3. A user can try to mint non-existent collections for free via `FantiumMinterV1.mint()` if `maxInvocations` is set. (https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumMinterV1.sol#L241)\n\n##### Recommendation\nWe recommend checking the existing `collectionId` and `tokenId`. An example of classical implementation:\n```\nrequire(_exists(tokenId), \"Nonexistent token\");\n# or\nfunction tokenURI(uint256 tokenId) public view virtual override\nreturns (string memory) {\n _requireMinted(tokenId);\n ...\n}\n```", + "protocol": "Fantium", + "report_date": "2023-01-10", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/README.md#1-contract-works-with-non-existent-collections-and-tokens", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/Fantium%20Security%20Audit%20Report.pdf" + }, + { + "title": "Undefined behavior for `mint`", + "content": "##### Description\n\nIn `FantiumMinterV1.mint()`, param `_to` is intended to be `_to Address to be the minted token's owner`. It's wrong because the final mint will be for `msg.sender` (https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumMinterV1.sol#L269).\n\n```\n# athlete -> 0x90F79bf6EB2c4f870365E785982E1f101E93b906\n# fan -> 0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65\nawait minterContract.connect(fan).mint(athlete.address, 1, \n{ value: 100000000000000 });\nconsole.log(\"ownerOf -> \", await nftContract.ownerOf(1000000)); \n# print fan -> 0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65\n```\n\n##### Recommendation\n\nWe recommend changing it: `fantiumNFTContract.mintTo(_to, thisTokenId);`\n", + "protocol": "Fantium", + "report_date": "2023-01-10", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/README.md#2-undefined-behavior-for-mint", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/Fantium%20Security%20Audit%20Report.pdf" + }, + { + "title": "An intruder can block any users", + "content": "##### Description\n\n`FantiumMinterV1.mint()` allows passing `_to`, which is not validated.\n\nAfter this line (https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumMinterV1.sol#L266), we can change the permit of some users. In a common way we need to have the `onlyPlatformManager` permission for this action.\n\n##### Recommendation\n\nWe recommend that you rethink the logic of `allowList`.\n", + "protocol": "Fantium", + "report_date": "2023-01-10", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/README.md#3-an-intruder-can-block-any-users", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/Fantium%20Security%20Audit%20Report.pdf" + }, + { + "title": "`FantiumNFTV1._owners` shadows `ERC721Upgradeable._owners`", + "content": "##### Description\n\nFantiumNFTV1 `mapping(uint256 => address) internal _owners` shadows ERC721Upgradeable `mapping(uint256 => address) private _owners`.\n\nThus, the `exists()` (https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L245-L248) function will not work correctly:\n```solidity\nfunction exists(uint256 _tokenId) public view returns (bool) {\n return _owners[_tokenId] != address(0);\n}\n```\n\n##### Recommendation\n\n1. Remove the FantiumNFTV1 `mapping(uint256 => address) internal _owners` line. \n2. Use the `ERC721Upgradeable.ownerOf()` method.\n", + "protocol": "Fantium", + "report_date": "2023-01-10", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/README.md#4-fantiumnftv1_owners-shadows-erc721upgradeable_owners", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/Fantium%20Security%20Audit%20Report.pdf" + }, + { + "title": "Insufficient role isolation", + "content": "##### Description\n\nRoles are not sufficiently isolated:\n1. `DEFAULT_ADMIN_ROLE` is allowed to run any operations on the contracts.\n2. By default, this and other roles are all assigned to a deployer.\n\nThis increases the surface for social engineering attacks.\n\n##### Recommendation\n\n`DEFAULT_ADMIN_ROLE` should be used to grant roles only and nothing else. The deployer may have this role, but they should not be granted any other roles.\n\n- https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L121,\n- https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L130,\n- https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumMinterV1.sol#L61,\n- https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumMinterV1.sol#L71,\n- https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumMinterV1.sol#L211,\n- https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumMinterV1.sol#L221\n\nIt creates confusion between a role that is supposed to manage the technical side of the contract and the role of the platform manager responsible for the business logic consistency. This creates difficulties in role management and has the potential to introduce errors related to the functionality permitted to each role.\n\nThus, it is recommended to remove these lines in [FantiumNFTV1](https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L18):\n```solidity\n_grantRole(PLATFORM_MANAGER_ROLE, msg.sender);\n...\n_grantRole(UPGRADER_ROLE, msg.sender);\n...\nhasRole(DEFAULT_ADMIN_ROLE, msg.sender),\n...\nhasRole(DEFAULT_ADMIN_ROLE, msg.sender), \n```\n\nAlso, remove the lines in [FantiumMinterV1](https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumMinterV1.sol#L96-L98):\n```solidity\nhasRole(DEFAULT_ADMIN_ROLE, msg.sender),\n...\nhasRole(DEFAULT_ADMIN_ROLE, msg.sender),\n...\n_grantRole(KYC_MANAGER_ROLE, msg.sender);\n_grantRole(PLATFORM_MANAGER_ROLE, msg.sender);\n_grantRole(UPGRADER_ROLE, msg.sender);\n```", + "protocol": "Fantium", + "report_date": "2023-01-10", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/README.md#1-insufficient-role-isolation", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/Fantium%20Security%20Audit%20Report.pdf" + }, + { + "title": "Insufficient constraint checks", + "content": "##### Description\n\nInsufficient constraint checks increase the human error probability: a platform manager may enter incorrect data and break the contract logic. \n\n`addCollection()` (https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L266):\n* no zero address check for `athleteAddress`\n* no constraint checks for `athletePrimarySalesPercentage`, `athleteSecondarySalesPercentage`\n\nNo check for the `collectionId` existence:\n* `updateCollectionName` (https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L297)\n* `updateCollectionAthleteAddress` (https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L308)\n* `toggleCollectionIsPaused` (https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L319)\n* `updateCollectionPrice` (https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L330)\n* `updateCollectionMaxInvocations` (https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L342)\n* `updateCollectionTier` (https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L353)\n* `updateCollectionBaseURI` (https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L366)\n* `updateCollectionAthleteName` (https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L378)\n* `updateCollectionAthletePrimaryMarketRoyaltyPercentage` (https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L397)\n* `updateCollectionAthleteSecondaryMarketRoyaltyPercentage` (https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L422)\n\nNo check `maxInvocations < ONE_MILLION` check:\n* `updateCollectionMaxInvocations` (https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L342)\n\nNo zero address check:\n* `updateCollectionAthleteAddress` (https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L308)\n* `updateFantiumPrimarySaleAddress` (https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L467)\n* `updateFantiumSecondarySaleAddress` (https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L479)\n* `updateFantiumMinterAddress` (https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L508)\n* `updateFantiumNFTAddress` (https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumMinterV1.sol#L322)\n\n`updateTiers` (https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L493):\n* no check for `_priceInWei > 0`\n* no check for `_maxInvocations < ONE_MILLION`\n\n`fantiumPrimarySalesAddress` in `getPrimaryRevenueSplits()` (https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L600) may be zero. Consider setting it to a non-zero address in the contract's initializer so it is never zero.\n\n##### Recommendation\n\nIt is recommended to add all necessary checks.\n", + "protocol": "Fantium", + "report_date": "2023-01-10", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/README.md#2-insufficient-constraint-checks", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/Fantium%20Security%20Audit%20Report.pdf" + }, + { + "title": "DefaultOperatorFiltererUpgradeable initializer is not called", + "content": "##### Description\n*FantiumNFTV1* class inherits *DefaultOperatorFiltererUpgradeable* but it's initializer is not called together with other base classes initializers in the `initialize()` method at https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L168.\nDue to this, the full functionality related to OperatorFilterRegistry becomes unavailable.\n##### Recommendation\nWe recommend adding the `DefaultOperatorFilterer_init()` call to *FantiumNFTV1* initializer.", + "protocol": "Fantium", + "report_date": "2023-01-10", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/README.md#3-defaultoperatorfiltererupgradeable-initializer-is-not-called", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/Fantium%20Security%20Audit%20Report.pdf" + }, + { + "title": "Unsafe Math", + "content": "##### Description\n\nIn the project, unvalidated params with unsafe math are used. For example, it's dangerous logic (https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L620):\n```\nunchecked {\n // fantiumRevenue_ is always <=25, so guaranteed to never underflow\n collectionFunds = _price - athleteRevenue_;\n}\n```\n\nIn this case, `collection.athletePrimarySalesPercentage`, `_price`, `_collectionId` are not validated fully.\n\n##### Recommendation\n\nWe recommend using only safe math for all operations in the project.\n", + "protocol": "Fantium", + "report_date": "2023-01-10", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/README.md#4-unsafe-math", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/Fantium%20Security%20Audit%20Report.pdf" + }, + { + "title": "Use `transfer` instead of `call`", + "content": "##### Description\n\nIf the project work with other contracts is not implied, then the `transfer` method is safer (this forwards 2300 gas).\n\n##### Recommendation\n\nWe recommend using `transfer` to avoid potential re-entrancy.\n", + "protocol": "Fantium", + "report_date": "2023-01-10", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/README.md#5-use-transfer-instead-of-call", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/Fantium%20Security%20Audit%20Report.pdf" + }, + { + "title": "Broken `operatorFilterRegistry` may lead to DOS", + "content": "##### Description\n\nIf the `operatorFilterRegistry` (https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/openseaFilterUpgradeable/OperatorFiltererUpgradeable.sol#L10) is broken and reverts on every transaction, then all transfers with `modifier onlyAllowedOperator` (https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/openseaFilterUpgradeable/OperatorFiltererUpgradeable.sol#L32) will be locked.\n\n##### Recommendation\n\nIt is recommended to allow the platform manager to update `operatorFilterRegistry` (https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/openseaFilterUpgradeable/OperatorFiltererUpgradeable.sol#L10).\n", + "protocol": "Fantium", + "report_date": "2023-01-10", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/README.md#6-broken-operatorfilterregistry-may-lead-to-dos", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/Fantium%20Security%20Audit%20Report.pdf" + }, + { + "title": "Wrong conditions in `mint`", + "content": "##### Description\n\nWrong conditions in `mint` (https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumMinterV1.sol#L200):\n```solidity\nif (\n !hasRole(PLATFORM_MANAGER_ROLE, msg.sender) ||\n !hasRole(DEFAULT_ADMIN_ROLE, msg.sender)\n) {\n require(isAddressKYCed(msg.sender), \"Address not KYCed\");\n}\nIFantiumNFT.Collection memory collection = fantiumNFTContract\n .getCollection(_collectionId);\n// sender must be on allow list or Admin or Manager \n// if the collection is paused\nif (\n !hasRole(PLATFORM_MANAGER_ROLE, msg.sender) &&\n !hasRole(DEFAULT_ADMIN_ROLE, msg.sender)\n) {\n require(\n !collection.paused ||\n isAddressOnAllowList(_collectionId, msg.sender),\n \"Purchases are paused and not on allow list\"\n );\n}\n```\n\n##### Recommendation\n\nThe correct (but not the optimal) form is to use the \"&&\" operator:\n```solidity\nif (\n !hasRole(PLATFORM_MANAGER_ROLE, msg.sender) &&\n !hasRole(DEFAULT_ADMIN_ROLE, msg.sender)\n)\n```\n\n**But the best way would be to restrict privileges and disallow unnecessary access altogether:**\n```solidity\nrequire(isAddressKYCed(msg.sender), \"Address not KYCed\");\nIFantiumNFT.Collection memory collection = fantiumNFTContract\n .getCollection(_collectionId);\n \nrequire(!collection.paused, \"Purchases are paused\");\n```\n", + "protocol": "Fantium", + "report_date": "2023-01-10", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/README.md#7-wrong-conditions-in-mint", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/Fantium%20Security%20Audit%20Report.pdf" + }, + { + "title": "Multiple issues when migrating to new fantiumNFTContractAddress", + "content": "##### Description\nFantiumMinterV1 allows setting a new fantiumNFTContractAddress with updateFantiumNFTAddress(). It only changes the address stored but does not affect other scenarios.\n\n1) The new fantiumNFTContractAddress will have an empty `tokenId` and `collections` sold, allowing minting NFTs with the same `tokenId`.\n2) Mapping `collectionIdToAllowList` remains unchanged, thus the old allowlist for old collections will be active for new collections.\n3) Minting on the old contract will be frozen.\n\nWhen a new fantiumNFTContractAddress is set, it will be possible.\nWhen `FantiumMinterV1` changes its `fantiumNFTContractAddress`, its stored mapping `collectionIdToAllowList` remains unchanged. \n\n- https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumMinterV1.sol#L322-L329\n\n##### Recommendation\n\nThe general recommendation is to update code on scenarios of migration to the new FantiumNFTV1. We assume some possible steps are as follows:\n\n- store the allowlist at `FantiumNFTV1` only\n- remove migration functionality at all\n", + "protocol": "Fantium", + "report_date": "2023-01-10", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/README.md#8-multiple-issues-when-migrating-to-new-fantiumnftcontractaddress", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/Fantium%20Security%20Audit%20Report.pdf" + }, + { + "title": "maxInvocation limits in two contracts are not synchronized", + "content": "##### Description\nFantiumMinterV1 imply that maxInvocation for collection is limited by 1 mln. But multiple setter functions in FantiumNFTV1 allow maxinvocation for collections being above 1 mln.\n\n- https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L346\n- https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L493-L505\n\n##### Recommendation\n\nFor every function that modifies `maxInvocation`, we recommend checking that it is limited by 1 mln.\n", + "protocol": "Fantium", + "report_date": "2023-01-10", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/README.md#9-maxinvocation-limits-in-two-contracts-are-not-synchronized", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/Fantium%20Security%20Audit%20Report.pdf" + }, + { + "title": "Likely mistake in roles allowed to mint()", + "content": "##### Description\nAt FantiumMinterV1 function mint() has the following lines:\n\n```\n// sender must be KYCed or Admin or Manager\n if (\n !hasRole(PLATFORM_MANAGER_ROLE, msg.sender) ||\n !hasRole(DEFAULT_ADMIN_ROLE, msg.sender)\n ) {\n require(isAddressKYCed(msg.sender), \"Address not KYCed\");\n }\n```\n\nmsg.sender is required to be KYCed, except for the case when it has both a PlatfromManager and DefaultManager role.\nBut the comment states that `sender must be KYCed or Admin or Manager`.\nThus, it is not expected in this function that it will revert in case when PlatformManager calls without the DefaultAdmin role (or DefaultAdmin without the PlatformManager role).\n\n- https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumMinterV1.sol#L210-L230\n\n##### Recommendation\n\nAs the expected behavior is likely written in the comments, we recommend changing `||` to `&&` in the line above. It will correlate with the following lines of code where the same requires checking with `&&`.\n", + "protocol": "Fantium", + "report_date": "2023-01-10", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/README.md#10-likely-mistake-in-roles-allowed-to-mint", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/Fantium%20Security%20Audit%20Report.pdf" + }, + { + "title": "Frontrun can create alternative NFT markets when price goes up", + "content": "##### Description\nFantiumNFTV1 allows upgrading the price of NFTs. When the price for a collection is set higher by calling updateCollectionPrice(), an attacker can front-run this price increase, buy many NFT tokens, and arrange secondary markets for these tokens. The price can be lower than the one set after updateCollectionPrice().\n\n##### Recommendation\n\nThe issue is hard to mitigate. One of the options is to introduce workflow when a caller pauses minting before calling updateCollectionPrice().\n", + "protocol": "Fantium", + "report_date": "2023-01-10", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/README.md#11-frontrun-can-create-alternative-nft-markets-when-price-goes-up", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/Fantium%20Security%20Audit%20Report.pdf" + }, + { + "title": "Every `priceInWei` in collections requires updating after `updatePaymentToken`", + "content": "##### Description\n\nIn commit https://github.com/metaxu-art/fantium-smart-contracts/commit/e79ed7dddabc482c56f7828bd9a8725fbbeca2f5 a new method will update the payment method (https://github.com/metaxu-art/fantium-smart-contracts/blob/e79ed7dddabc482c56f7828bd9a8725fbbeca2f5/contracts/FantiumNFTV1.sol#L717).\n```\nfunction updatePaymentToken(\n address _address\n) external onlyRole(PLATFORM_MANAGER_ROLE) {\n require(_address != address(0));\n erc20PaymentToken = _address;\n}\n```\n\nTokens have different decimals, so after calling `updatePaymentToken` it will be necessary to update the price for each collection.\n\n##### Recommendation\n\nWe recommend updating `erc20PaymentToken` to check that the decimals have not changed. Otherwise, you will have to update each price as it corresponds to the previous token.\n", + "protocol": "Fantium", + "report_date": "2023-01-10", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/README.md#12-every-priceinwei-in-collections-requires-updating-after-updatepaymenttoken", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/Fantium%20Security%20Audit%20Report.pdf" + }, + { + "title": "Use general safeTransferFrom", + "content": "##### Description\n\nIn commit e79ed7dddabc482c56f7828bd9a8725fbbeca2f5, it is required to check the success of the transfer at the following lines:\n- https://github.com/metaxu-art/fantium-smart-contracts/blob/e79ed7dddabc482c56f7828bd9a8725fbbeca2f5/contracts/FantiumNFTV1.sol#L372\n- https://github.com/metaxu-art/fantium-smart-contracts/blob/e79ed7dddabc482c56f7828bd9a8725fbbeca2f5/contracts/FantiumNFTV1.sol#L380.\n\n##### Recommendation\n\nIt is recommended to always use the `safeTransferFrom()` function when sending tokens.\n", + "protocol": "Fantium", + "report_date": "2023-01-10", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/README.md#13-use-general-safetransferfrom", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/Fantium%20Security%20Audit%20Report.pdf" + }, + { + "title": "Support additional EIPs", + "content": "##### Description\n\nThe project uses `EIP2981`. For example, `FantiumNFTV1` cannot support this EIP via the `supportsInterface` view method.\n\n```\n# In supportsInterface\ninterfaceId == type(IEIP2981).interfaceId\ninterfaceId == type(IEIP2981RoyaltyOverride).interfaceId\n```\n\n##### Recommendation\nWe recommend adding supported EIPs in the `supportsInterface` method if needed.\n", + "protocol": "Fantium", + "report_date": "2023-01-10", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/README.md#1-support-additional-eips", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/Fantium%20Security%20Audit%20Report.pdf" + }, + { + "title": "No additional information via events", + "content": "##### Description\n\nThese events do not contain all information about the update:\n- `PlatformUpdated` (https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L90)\n- `CollectionUpdated` (https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L86)\n\nAnd for method there is no event:\n- `updateTiers` https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L493\n\n##### Recommendation\nWe recommend adding more event info for user convenience.\n", + "protocol": "Fantium", + "report_date": "2023-01-10", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/README.md#2-no-additional-information-via-events", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/Fantium%20Security%20Audit%20Report.pdf" + }, + { + "title": "Duplicate variables", + "content": "##### Description\n\nThe FantiumMinterV1 variables `fantiumNFTContract` and `fantiumNFTContractAddress` duplicate each other.\n\n##### Recommendation\n\nIt is recommended to remove either `fantiumNFTContract` or `fantiumNFTContractAddress` to save gas.\n", + "protocol": "Fantium", + "report_date": "2023-01-10", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/README.md#3-duplicate-variables", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/Fantium%20Security%20Audit%20Report.pdf" + }, + { + "title": "Duplicate assignments", + "content": "##### Description\n\nThere are duplicate lines: \n* https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L281\n* https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L283\n\n##### Recommendation\nIt is recommended to remove one of the lines to save gas.\n", + "protocol": "Fantium", + "report_date": "2023-01-10", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/README.md#4-duplicate-assignments", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/Fantium%20Security%20Audit%20Report.pdf" + }, + { + "title": "An athlete cannot update their address", + "content": "##### Description\n\nAn athlete cannot update their address in `updateCollectionAthleteAddress()` (https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L308).\n\n##### Recommendation\n\nIt is recommended to check if this behavior is intended.\n", + "protocol": "Fantium", + "report_date": "2023-01-10", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/README.md#5-an-athlete-cannot-update-their-address", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/Fantium%20Security%20Audit%20Report.pdf" + }, + { + "title": "Variables not used", + "content": "##### Description\n\nThe FantiumNFTV1 contract does not use variables:\n\n- `KYC_Manager`\n- `FIELD_FANTIUM_PRIMARY_MARKET_ROYALTY_PERCENTAGE`\n- `tierSet`\n\nLines:\n\n- https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L37\n- https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L45\n- https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L33\n\n##### Recommendation\n\nWe recommend removing these variables.\n", + "protocol": "Fantium", + "report_date": "2023-01-10", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/README.md#6-variables-not-used", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/Fantium%20Security%20Audit%20Report.pdf" + }, + { + "title": "ERC-1155 multi-token standard is not used", + "content": "##### Description\n\nERC-1155 is a smart contract interface that can represent and control any number of fungible and non-fungible token types. In this way, the ERC-1155 token can do the same functions as an [ERC-20](https://ethereum.org/en/developers/docs/standards/tokens/erc-20/) and [ERC-721](https://ethereum.org/en/developers/docs/standards/tokens/erc-721/) token, and even both at the same time. And best of all, improving the functionality of both standards, making it more efficient, and correcting obvious implementation errors on the ERC-20 and ERC-721 standards.\n\nThe ERC-1155 token is described fully in [EIP-1155](https://eips.ethereum.org/EIPS/eip-1155).\n\n\n##### Recommendation\n\nIt is recommended to take note of the [EIP-1155](https://eips.ethereum.org/EIPS/eip-1155) multi-token standard: it can be used for NFT collections.\n", + "protocol": "Fantium", + "report_date": "2023-01-10", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/README.md#7-erc-1155-multi-token-standard-is-not-used", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/Fantium%20Security%20Audit%20Report.pdf" + }, + { + "title": "`operatorFilterRegistry` cannot be updated", + "content": "##### Description\n\nThe `operatorFilterRegistry` (https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/openseaFilterUpgradeable/OperatorFiltererUpgradeable.sol#L10) constant cannot be updated:\n```solidity\nIOperatorFilterRegistry constant operatorFilterRegistry =\n IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E);\n```\n\n##### Recommendation\n\nIt is recommended to set `operatorFilterRegistry` in the initializer or in the constructor and also add a method to update the variable. \n\nThe update method must allow setting the variable to zero: this allows replacing the `code.length` (https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/openseaFilterUpgradeable/OperatorFiltererUpgradeable.sol#L34) check in the `onlyAllowedOperator` modifier to a zero address check.\n", + "protocol": "Fantium", + "report_date": "2023-01-10", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/README.md#8-operatorfilterregistry-cannot-be-updated", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/Fantium%20Security%20Audit%20Report.pdf" + }, + { + "title": "Unsynchronized roles in two contracts, likely not designed", + "content": "##### Description\nTwo contracts share the same roles and likely expect them to be the same.\n`FantiumNFTV1` may expect that a function with modifiers onlyPlatformManager() and onlyAthlete() is allowed for the same `PLATFORM_MANAGER_ROLE`, as the `PLATFORM_MANAGER_ROLE` is allowed to mint NFT tokens - but this `PLATFORM_MANAGER_ROLE` is stored at FantiumMinterV1 and can be different.\n\n- https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumMinterV1.sol#L25-L28\n- https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L37-L40\n\n##### Recommendation\n\nIf roles are expected to have the same addresses on both contracts, it is recommended to consider one single storage for roles OR remove doubled roles OR implement different role namings.\n", + "protocol": "Fantium", + "report_date": "2023-01-10", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/README.md#9-unsynchronized-roles-in-two-contracts-likely-not-designed", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/Fantium%20Security%20Audit%20Report.pdf" + }, + { + "title": "NFT Pause is limited", + "content": "##### Description\nThe FantiumNFTV1 pause for collections blocks only new mintings. In addition, the address at allowedList still can mint.\n\nTransfers remain allowed. So the scenario is possible when `toggleCollectionIsPaused()` is front run, and NFT can be traded on secondary markets as transfers are still allowed.\n\n- https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L323\n\n##### Recommendation\n\nConsider renaming the pause to `isMintAllowed` or add a transfer pausing if it is required by the pause design.\n", + "protocol": "Fantium", + "report_date": "2023-01-10", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/README.md#10-nft-pause-is-limited", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/Fantium%20Security%20Audit%20Report.pdf" + }, + { + "title": "Tier information upgrading flow likely not designed", + "content": "##### Description\nWe outline that updating Tiers in `tiers` with dedicated functions do not change tier information stored at Collections in `collections`.\n\nIn addition, collection parameters related to tiers can be easily changed and thus deviate from predefined Tier stores at `tiers`. \n\n- https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L493-L505\n\n##### Recommendation\n\nWe recommend either removing Tiers at all or removing allowance to modify Tier information in collections.\n", + "protocol": "Fantium", + "report_date": "2023-01-10", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/README.md#11-tier-information-upgrading-flow-likely-not-designed", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/Fantium%20Security%20Audit%20Report.pdf" + }, + { + "title": "Current collectionIdToAllowList likely has practical limits", + "content": "##### Description\n`allowList` is checked when `mint()` happens at `FantiumMinterV1`. It always sets false for an address (buyer). But if it is true, it allows only one mint for an address when a collection is paused. This behavior is strange and likely not to be designed.\n\n- https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumMinterV1.sol#L225-L266\n\n##### Recommendation\n\nWe recommend designing a more clear flow for `collectionIdToAllowList` and its behavior during pauses. By the way, we assume that the current `collectionIdToAllowList` behaves as designed and no code modification is needed.\n", + "protocol": "Fantium", + "report_date": "2023-01-10", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/README.md#12-current-collectionidtoallowlist-likely-has-practical-limits", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/Fantium%20Security%20Audit%20Report.pdf" + }, + { + "title": "The addCollection() function can be made external", + "content": "##### Description\nThe `addCollection()` function at (https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L272) is defined as public. As the function is not used for calls from smart contracts, it can be made external to save gas.\n##### Recommendation\nWe recommend making the `addCollection()` function external.", + "protocol": "Fantium", + "report_date": "2023-01-10", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/README.md#13-the-addcollection-function-can-be-made-external", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/Fantium%20Security%20Audit%20Report.pdf" + }, + { + "title": "The field baseURI might not be initialized", + "content": "##### Description\nThe `tokenURI()` method uses the *baseURI* field at (https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L236) which is meant to be initialized by the `updateBaseURI()` method. It is not verified whether the method was called during the contract initialization. This can result in an incorrect output of URI address in case collectionURI was not initialized.\n##### Recommendation\nWe recommend checking whether the baseURI field was initialized before using it.", + "protocol": "Fantium", + "report_date": "2023-01-10", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/README.md#14-the-field-baseuri-might-not-be-initialized", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/Fantium%20Security%20Audit%20Report.pdf" + }, + { + "title": "Redundant check for zero address in the mintTo() function", + "content": "##### Description\n\nThe check is redundant as the check on the next line at https://github.com/metaxu-art/fantium-smart-contracts/blob/cb2d97bc30c40321991fe5ab8fc798babba1610f/contracts/FantiumNFTV1.sol#L208\n```\nrequire(fantiumMinterAddress != address(0), \"Fantium Minter not set\");\n```\n\n##### Recommendation\nWe recommend removing the redundant check to save gas.", + "protocol": "Fantium", + "report_date": "2023-01-10", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/README.md#15-redundant-check-for-zero-address-in-the-mintto-function", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/Fantium%20Security%20Audit%20Report.pdf" + }, + { + "title": "New allocation mechanics for `allowList` can be bypassed when allocation is updated", + "content": "##### Description\n\nFix in commit https://github.com/metaxu-art/fantium-smart-contracts/commit/fdb089fa02c36560645f5ae7a3ab06d63f37ee1f introduced a new data type for `allowList`. Now it is a mapping storing the allocation for a user in a collection:\n`mapping(uint256 => mapping(address => uint256)) public collectionIdToAllowList`\n\nAllocation is the number of tokens allowed to the mint for an address. Also, two new functions set these allocations:\n`function addAddressToAllowListWithAllocation(uint256 _collectionId,address _address,uint256 _allocation`\n`function reduceAllowListAllocation(uint256 _collectionId,address _address,bool _completely)`\n\nThese two functions can be bypassed in some scenarios:\n1) `addAddressToAllowListWithAllocation()` is a setter that can be used to increase or decrease the allocation. When for example, the allocation is updated from 5 to 10, the address can front-run the update, buy 5 NFTs, wait for the update confirmation and buy an additional 10 NFTs as it is a newly updated allocation. Thus, the allocation update allows us to bypass of allocation limits and purchase additional NFTs.\n2) The same thing for `reduceAllowListAllocation()`. But it can only be exploited when `_completely` is used. The impact here is limited as the worst scenario allows purchasing the previous allocation before the update.\n\nIn addition, `reduceAllowListAllocation()` decreases the allocation by one point per call. For instance, it can be costly to decrease the allocation from 20 to 5.\n\n##### Recommendation\n\nWe recommend removing setters and implementing `increase`/`decrease` mechanics.\n\n1) it is better if `addAddressToAllowListWithAllocation` increments the allocations like:\n```\ncollectionIdToAllowList[_collectionId][_address] += _allocationAdded\n```\n\n2) it is better if `reduceAllowListAllocation` does the same thing when decreasing:\n\n```\ncollectionIdToAllowList[_collectionId][_address] -= _allocationReduced\n```\n", + "protocol": "Fantium", + "report_date": "2023-01-10", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/README.md#16-new-allocation-mechanics-for-allowlist-can-be-bypassed-when-allocation-is-updated", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/Fantium%20Security%20Audit%20Report.pdf" + }, + { + "title": "Optimize gas", + "content": "##### Description\n\nIn commit https://github.com/metaxu-art/fantium-smart-contracts/commit/e79ed7dddabc482c56f7828bd9a8725fbbeca2f5 the check is redundant:\n- https://github.com/metaxu-art/fantium-smart-contracts/blob/e79ed7dddabc482c56f7828bd9a8725fbbeca2f5/contracts/FantiumNFTV1.sol#L316\n\n```\nrequire(\n IERC20(erc20PaymentToken).allowance(msg.sender, address(this)) >=\n collection.priceInWei,\n \"ERC20 allowance too low\"\n);\n```\n\nThis check is optional, `transferFrom` will revert if approval is absent.\n\n##### Recommendation\nWe recommend removing the redundant check to save gas.", + "protocol": "Fantium", + "report_date": "2023-01-10", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/README.md#17-optimize-gas", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Fantium/Fantium/Fantium%20Security%20Audit%20Report.pdf" + }, + { + "title": "Possibility of the ownership transfer to an uncontrolled address", + "content": "##### Description\nThe [transfer of the ownership](https://github.com/p2p-org/eth-staking-fee-distributor-contracts/blob/4bac8f636d7ba14244612bcfb9e85f338feba6e3/contracts/access/Ownable.sol#L47) can be performed to an arbitrary account whether or not it is controlled by the current authority.\nAfter the transfer to an uncontrolled account, the ownership will be lost.\n##### Recommendation\nWe recommend using a two-step ownership transfer procedure, including the confirmation (accept) of the ownership transfer.", + "protocol": "P2P.org", + "report_date": "2022-12-29", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/P2P.org/ETH2%20Depositor%20&%20ETH%20Staking%20Fee%20Distributor%20(v.1)/README.md#1-possibility-of-the-ownership-transfer-to-an-uncontrolled-address", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/P2P.org/ETH2%20Depositor%20&%20ETH%20Staking%20Fee%20Distributor%20(v.1)/P2P.org_ETH2%20Depositor%20&%20ETH%20Staking%20Fee%20Distributor%20Smart%20Contracts%20Audit%20Report.pdf" + }, + { + "title": "Ether stuck in the `FeeDistributor`", + "content": "##### Description\nIf one of the fee receivers can't accept ether (i.e the transaction will revert or consume too much gas), no ether can be [withdrawn](https://github.com/p2p-org/eth-staking-fee-distributor-contracts/blob/4bac8f636d7ba14244612bcfb9e85f338feba6e3/contracts/feeDistributor/FeeDistributor.sol#L231).\nAlthough a new instance can be redeployed, some ether may stuck in the recent instance.\n##### Recommendation\nWe recommend implementing the functionality to migrate from a stuck `FeeDistributor` instance to a new one.", + "protocol": "P2P.org", + "report_date": "2022-12-29", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/P2P.org/ETH2%20Depositor%20&%20ETH%20Staking%20Fee%20Distributor%20(v.1)/README.md#2-ether-stuck-in-the-feedistributor", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/P2P.org/ETH2%20Depositor%20&%20ETH%20Staking%20Fee%20Distributor%20(v.1)/P2P.org_ETH2%20Depositor%20&%20ETH%20Staking%20Fee%20Distributor%20Smart%20Contracts%20Audit%20Report.pdf" + }, + { + "title": "The depositContract variable does not have the optimal type", + "content": "##### Description\nThe `depositContract` variable is initialized only in the constructor and not changed any more. \nhttps://github.com/p2p-org/p2p-eth2-depositor/blob/main/src/P2pEth2Depositor.sol#L15\nThe current variable type (mutable) is designed for variables that are supposed to be changed during lifecycle. \nReading such variables consumes more gas than reading immutable variables.\n##### Recommendation\nWe recommend adding the immutable keyword to the `depositContract` variable.", + "protocol": "P2P.org", + "report_date": "2022-12-29", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/P2P.org/ETH2%20Depositor%20&%20ETH%20Staking%20Fee%20Distributor%20(v.1)/README.md#1-the-depositcontract-variable-does-not-have-the-optimal-type", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/P2P.org/ETH2%20Depositor%20&%20ETH%20Staking%20Fee%20Distributor%20(v.1)/P2P.org_ETH2%20Depositor%20&%20ETH%20Staking%20Fee%20Distributor%20Smart%20Contracts%20Audit%20Report.pdf" + }, + { + "title": "Unused ReentrancyGuard contract", + "content": "##### Description\nAt line \nhttps://github.com/p2p-org/p2p-eth2-depositor/blob/9ad1803294a968e9bc4ce9a24e37b0f312a07d0e/src/P2pEth2Depositor.sol#L10\n`P2pEth2Depositor` inherits `ReentrancyGuard`, but the functions of this contract are not used.\nInheritance of unnecessary code generally increases the likelihood of vulnerabilities.\n##### Recommendation\nWe recommend removing the `ReentrancyGuard` inheritance.", + "protocol": "P2P.org", + "report_date": "2022-12-29", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/P2P.org/ETH2%20Depositor%20&%20ETH%20Staking%20Fee%20Distributor%20(v.1)/README.md#2-unused-reentrancyguard-contract", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/P2P.org/ETH2%20Depositor%20&%20ETH%20Staking%20Fee%20Distributor%20(v.1)/P2P.org_ETH2%20Depositor%20&%20ETH%20Staking%20Fee%20Distributor%20Smart%20Contracts%20Audit%20Report.pdf" + }, + { + "title": "Excess transformation `IDepositContract` -> `address` -> `IDepositContract`", + "content": "##### Description\nAt line \nhttps://github.com/p2p-org/p2p-eth2-depositor/blob/9ad1803294a968e9bc4ce9a24e37b0f312a07d0e/src/P2pEth2Depositor.sol#L83\nexcess transformation can be removed.\n\n***\n\n##### Recommendation\nIt is recommended to replace the line with \n```\n depositContract.deposit{value: collateral}(\n pubkeys[i],\n withdrawal_credentials[i],\n signatures[i],\n deposit_data_roots[i]\n );\n```", + "protocol": "P2P.org", + "report_date": "2022-12-29", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/P2P.org/ETH2%20Depositor%20&%20ETH%20Staking%20Fee%20Distributor%20(v.1)/README.md#3-excess-transformation-idepositcontract---address---idepositcontract", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/P2P.org/ETH2%20Depositor%20&%20ETH%20Staking%20Fee%20Distributor%20(v.1)/P2P.org_ETH2%20Depositor%20&%20ETH%20Staking%20Fee%20Distributor%20Smart%20Contracts%20Audit%20Report.pdf" + }, + { + "title": "No null checks for recipient in s_referrerConfig", + "content": "##### Description\nIf `recipient` in `s_referrerConfig` is a null address, then there is no need to calculate `referrerAmount`, because `referrerAmount` will always be 0.\nAlso, `referrerAmount` will be redundant for `serviceAmount`. Additionaly, we can bypass calling the `sendValue` with zero value and null address.\n\nhttps://github.com/p2p-org/eth-staking-fee-distributor-contracts/blob/4bac8f636d7ba14244612bcfb9e85f338feba6e3/contracts/feeDistributor/FeeDistributor.sol#L256 \nhttps://github.com/p2p-org/eth-staking-fee-distributor-contracts/blob/4bac8f636d7ba14244612bcfb9e85f338feba6e3/contracts/feeDistributor/FeeDistributor.sol#L244 \nhttps://github.com/p2p-org/eth-staking-fee-distributor-contracts/blob/4bac8f636d7ba14244612bcfb9e85f338feba6e3/contracts/feeDistributor/FeeDistributor.sol#L247 \n##### Recommendation\nWe recommend adding a null check for `recipient` in `s_referrerConfig` in the `withdraw` function and update logic for gas saving.", + "protocol": "P2P.org", + "report_date": "2022-12-29", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/P2P.org/ETH2%20Depositor%20&%20ETH%20Staking%20Fee%20Distributor%20(v.1)/README.md#4-no-null-checks-for-recipient-in-s_referrerconfig", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/P2P.org/ETH2%20Depositor%20&%20ETH%20Staking%20Fee%20Distributor%20(v.1)/P2P.org_ETH2%20Depositor%20&%20ETH%20Staking%20Fee%20Distributor%20Smart%20Contracts%20Audit%20Report.pdf" + }, + { + "title": "Extra inheritance", + "content": "##### Description\nThe `OrderMixin` contract inherits the `NonceManager` contract, and the `PredicateHelper` contract inherits the `NonceManager` contract. You can remove the `NonceManager` contract from the `OrderMixin` inheritance chain because the `OrderMixin` contract inherits `PredicateHelper` and does not use the `NonceManager` contract code.\n\n***\n\n##### Recommendation\nWe recommend removing the `NonceManager` contract from inheritance for the `OrderMixin` contract.\n\n", + "protocol": "1inch", + "report_date": "2022-11-10", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Aggregation%20Router%20V5/README.md#1-extra-inheritance", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Aggregation%20Router%20V5/1inch%20Aggregation%20Router%20V5%20Security%20Audit%20Report.pdf" + }, + { + "title": "Spelling mistakes", + "content": "##### Description\nSome texts have spelling mistakes:\n1) `SYBMOL` -> `SYMBOL` (bad input param)\n https://github.com/1inch/solidity-utils/blob/eec6b523860af5215a8dd196fe3aff3a4d252fc9/contracts/libraries/UniERC20.sol#L62\n2) `signuture` -> `signature`\n https://github.com/1inch/limit-order-protocol/blob/d8437885744543e3f057e84e1b0a05c4c211c553/contracts/OrderRFQMixin.sol#L98\n\n##### Recommendation\nWe recommend correcting them.\n\n", + "protocol": "1inch", + "report_date": "2022-11-10", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Aggregation%20Router%20V5/README.md#2-spelling-mistakes", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Aggregation%20Router%20V5/1inch%20Aggregation%20Router%20V5%20Security%20Audit%20Report.pdf" + }, + { + "title": "Null check", + "content": "##### Description\nSome parameters have no null checks:\nhttps://github.com/1inch/1inch-contract/blob/8aa5ec4b4871b1d63bb045ddb78aaf7c5dc84dfa/contracts/AggregationRouterV5.sol#L22\n\n##### Recommendation\nWe recommend adding a null check for `clipperExchange`.\n\n", + "protocol": "1inch", + "report_date": "2022-11-10", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Aggregation%20Router%20V5/README.md#3-null-check", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Aggregation%20Router%20V5/1inch%20Aggregation%20Router%20V5%20Security%20Audit%20Report.pdf" + }, + { + "title": "Reduce gas cost", + "content": "##### Description\nReduce gas cost for some functions:\nhttps://github.com/1inch/solidity-utils/blob/eec6b523860af5215a8dd196fe3aff3a4d252fc9/contracts/libraries/UniERC20.sol#L99\n\n##### Recommendation\nWe recommend adding `unchecked block` for `len++`.\n\n", + "protocol": "1inch", + "report_date": "2022-11-10", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Aggregation%20Router%20V5/README.md#4-reduce-gas-cost", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Aggregation%20Router%20V5/1inch%20Aggregation%20Router%20V5%20Security%20Audit%20Report.pdf" + }, + { + "title": "Using `camelCase` style for variables", + "content": "##### Description\nVariable naming can be updated:\n- https://github.com/EnsoFinance/enso-weiroll/tree/9289118113f753d460a97d7c6ee72577e5c3f5eb/contracts/VM.sol#L43 `outdata` by `outData`\n- https://github.com/EnsoFinance/enso-weiroll/tree/9289118113f753d460a97d7c6ee72577e5c3f5eb/contracts/VM.sol#L99 `calleth` by `callEth`\n- https://github.com/EnsoFinance/enso-weiroll/tree/9289118113f753d460a97d7c6ee72577e5c3f5eb/contracts/CommandBuilder.sol#L35 `arglen` by `argLen`\n- https://github.com/EnsoFinance/enso-weiroll/tree/9289118113f753d460a97d7c6ee72577e5c3f5eb/contracts/CommandBuilder.sol#L92 `statevar` by `stateVar`\n- https://github.com/EnsoFinance/enso-weiroll/tree/9289118113f753d460a97d7c6ee72577e5c3f5eb/contracts/CommandBuilder.sol#L119 `argptr` by `argPtr`\n- https://github.com/EnsoFinance/enso-weiroll/tree/9289118113f753d460a97d7c6ee72577e5c3f5eb/contracts/CommandBuilder.sol#L169 `srcidx` by `srcIdx`\n- https://github.com/EnsoFinance/enso-weiroll/tree/9289118113f753d460a97d7c6ee72577e5c3f5eb/contracts/CommandBuilder.sol#L171 `destidx` by `destIdx`\n##### Recommendation\nWe recommend updating the variable naming in favour of code style improvement.\n\n", + "protocol": "Enso Finance", + "report_date": "2022-10-04", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Enso%20Finance/Weiroll/README.md#1-using-camelcase-style-for-variables", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Enso%20Finance/Weiroll/Weiroll%20Security%20Audit%20Report.pdf" + }, + { + "title": "Unused variables", + "content": "##### Description\nhttps://github.com/EnsoFinance/enso-weiroll/tree/9289118113f753d460a97d7c6ee72577e5c3f5eb/contracts/VM.sol#L22\n##### Recommendation\nWe recommend removing it or describing its functionality.\n", + "protocol": "Enso Finance", + "report_date": "2022-10-04", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Enso%20Finance/Weiroll/README.md#2-unused-variables", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Enso%20Finance/Weiroll/Weiroll%20Security%20Audit%20Report.pdf" + }, + { + "title": "Merge unchecked blocks", + "content": "##### Description\nSome `unchecked` blocks can be merged:\n- https://github.com/EnsoFinance/enso-weiroll/tree/9289118113f753d460a97d7c6ee72577e5c3f5eb/contracts/CommandBuilder.sol#L49\n- https://github.com/EnsoFinance/enso-weiroll/tree/9289118113f753d460a97d7c6ee72577e5c3f5eb/contracts/CommandBuilder.sol#L97\n##### Recommendation\nWe recommend merging it in favour of the code readability.\n", + "protocol": "Enso Finance", + "report_date": "2022-10-04", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Enso%20Finance/Weiroll/README.md#3-merge-unchecked-blocks", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Enso%20Finance/Weiroll/Weiroll%20Security%20Audit%20Report.pdf" + }, + { + "title": "Compiler version (gas saving)", + "content": "##### Description\nIn solidity code and config specified compiler version `0.8.11`, more modern compiler version can improve gas optimization.\n##### Recommendation\nWe recommend updating it to `0.8.16` for gas saving.\n\n\n", + "protocol": "Enso Finance", + "report_date": "2022-10-04", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Enso%20Finance/Weiroll/README.md#4-compiler-version-gas-saving", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Enso%20Finance/Weiroll/Weiroll%20Security%20Audit%20Report.pdf" + }, + { + "title": "Set credit limit by pausing the guardian", + "content": "##### Description\nPausing the guardian can set a new credit limit for users with the credit limit.\nhttps://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/Comptroller.sol#L1313\n##### Recommendation\nWe recommend updating the checks in the \"_setCreditLimit\" function.\n\n", + "protocol": "Iron Bank", + "report_date": "2022-09-05", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Iron%20Bank/README.md#1-set-credit-limit-by-pausing-the-guardian", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Iron%20Bank/IronBank%20Security%20Audit%20Report.pdf" + }, + { + "title": "Exchange rate vulnerability", + "content": "##### Description\nAn exchange rate bug for new pools and empty pools (without borrowers and suppliers) for CToken contracts without the 'internalCash' variable.\nFlow:\n1. Create cToken\n2. Mint cToken by user1 (1,000,000)\n3. Redeem cToken by user1 (999,999.999999)\n4. Transfer underlying (1,000,000) from user1 to market\n5. Mint cToken by user2 (1,000,000)\n6. Redeem cToken by user1 (user1 receive extra tokens)\n\n##### Recommendation\nWe recommend checking the exchange rate before the first mint or using the 'internalCash' value for all CToken contracts.", + "protocol": "Iron Bank", + "report_date": "2022-09-05", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Iron%20Bank/README.md#2-exchange-rate-vulnerability", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Iron%20Bank/IronBank%20Security%20Audit%20Report.pdf" + }, + { + "title": "Interest rate model update impacts the old time period", + "content": "##### Description\nAfter an admin changes the interest rate model parameters by using this function\nhttps://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/TripleSlopeRateModel.sol#L100\nindexes will be recalculated in the upcoming accrueInterest() function call. But this call applies new interest settings to the previous period of time which is not correct.\n##### Recommendation\nThe interest rate model parameters should be changed just after calling the accrueInterest() function for each asset. It can be done by creating a special service contract.\n\n", + "protocol": "Iron Bank", + "report_date": "2022-09-05", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Iron%20Bank/README.md#3-interest-rate-model-update-impacts-the-old-time-period", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Iron%20Bank/IronBank%20Security%20Audit%20Report.pdf" + }, + { + "title": "A flashloan will be broken if the USDT fee is more than zero", + "content": "##### Description\nLet's take a look at the flashloan flow. After doTransferOut a receiver gets `amount - fee`.\nhttps://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/CCollateralCapErc20.sol#L217\n\nThen a receiver's `onFlashLoan` function will be called with an incorrect amount. \nhttps://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/CCollateralCapErc20.sol#L224\n\nThen doTransferIn will transfer the repayment amount but the contract will receive the repayment `amount - fee`\nhttps://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/CCollateralCapErc20.sol#L231 and the`require` check will cause a revert. \nhttps://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/CCollateralCapErc20.sol#L235\n\n##### Recommendation\nThe flashloan() function should be rewritten taking into consideration the USDT fee value.\n", + "protocol": "Iron Bank", + "report_date": "2022-09-05", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Iron%20Bank/README.md#4-a-flashloan-will-be-broken-if-the-usdt-fee-is-more-than-zero", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Iron%20Bank/IronBank%20Security%20Audit%20Report.pdf" + }, + { + "title": "Undesired repay and/or liquidation of ex-credit account", + "content": "##### Description\nIn the IronBank, the `credit` functionality is introduced. An admin can trigger the [`setCreditLimit`](https://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/Comptroller.sol#L1302) function to mark some addresses like `credit` for specific `cToken` and set its `credit limit`. Such addresses can borrow a limited by `credit limit` amount of `cToken` without providing any collateral. Additionally, `setCreditLimit` can mark that an address is no longer `credit` and has become an ordinary account that requires collateral.\n\nUnfortunately, after becoming an ordinary account, the ex-credit account will be subject to repay and/or liquidation of its borrowed debt.\n\n##### Recommendation\nAlthough an attack is hard to implement since the `setCreditLimit` function is restricted to the admin, we recommend to disallow changing the state from the credit account to an ordinary account, e.g. by disallowing setting the credit limit less than the currently borrowed amount.\n\n", + "protocol": "Iron Bank", + "report_date": "2022-09-05", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Iron%20Bank/README.md#5-undesired-repay-andor-liquidation-of-ex-credit-account", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Iron%20Bank/IronBank%20Security%20Audit%20Report.pdf" + }, + { + "title": "Typos in descriptions", + "content": "##### Description\nSeveral typos:\n1. 'occured' instead of 'occurred'\n https://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/CTokenInterfaces.sol#L366\n https://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/CTokenInterfaces.sol#L412\n2. 'fucntions' instead of 'functions'\n https://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/PriceOracle/PriceOracleProxy.sol#L160\n https://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/PriceOracle/PriceOracleProxyIB.sol#L96\n3. 'supplys' instead of 'supplies'\n https://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/Comptroller.sol#L1144\n4. 'currenlty' instead of 'currently'\n https://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/PriceOracle/PriceOracleProxy.sol#L189\n https://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/PriceOracle/PriceOracleProxyIB.sol#L101\n5. 'settor' instead of 'setter'\n https://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/CErc20Delegator.sol#L54\n6. 'accuring' instead of 'accruing'\n https://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/CCollateralCapErc20.sol#L556\n https://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/CCollateralCapErc20.sol#L595\n https://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/CCollateralCapErc20CheckRepay.sol#L557\n https://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/CCollateralCapErc20CheckRepay.sol#L596\n https://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/CCollateralCapErc20NoInterest.sol#L557\n https://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/CCollateralCapErc20NoInterest.sol#L596\n https://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/CErc20.sol#L300\n https://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/CErc20.sol#L405\n https://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/CErc20.sol#L475\n https://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/CWrappedNative.sol#L659\n https://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/CWrappedNative.sol#L729\n7. 'sieze' instead of 'seize'\n https://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/Comptroller.sol#L595\n8. 'depreacted' instead of 'deprecated'\n https://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/ComptrollerStorage.sol#L100\n https://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/ComptrollerStorage.sol#L104\n https://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/ComptrollerStorage.sol#L108\n https://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/ComptrollerStorage.sol#L112\n https://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/ComptrollerStorage.sol#L116\n https://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/ComptrollerStorage.sol#L120\n https://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/ComptrollerStorage.sol#L136\n9. 'undelrying' instead of 'underlying'\n https://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/CToken.sol#L540\n https://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/CTokenCheckRepay.sol#L540\n https://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/CTokenNoInterest.sol#L569\n10. 'tather' instead of 'rather'\n https://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/CToken.sol#L1040\n https://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/CTokenCheckRepay.sol#L1059\n11. 'amnount' instead of 'amount'\n https://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/InterestRateModel.sol#L15\n https://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/InterestRateModel.sol#L28\n\n##### Recommendation\nWe recommend correcting them.\n\n", + "protocol": "Iron Bank", + "report_date": "2022-09-05", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Iron%20Bank/README.md#1-typos-in-descriptions", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Iron%20Bank/IronBank%20Security%20Audit%20Report.pdf" + }, + { + "title": "No null checks for input addresses", + "content": "##### Description\nSome code lacks a check for null address:\nadmin: https://github.com/ibdotxyz/compound-protocol/blob/8cd45803b48552e344e22be280c9e1c03ec8644a/contracts/PriceOracle/PriceOracleProxyIB.sol#L157\n\n##### Recommendation\nWe recommend adding null checks.\n\n", + "protocol": "Iron Bank", + "report_date": "2022-09-05", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Iron%20Bank/README.md#2-no-null-checks-for-input-addresses", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Iron%20Bank/IronBank%20Security%20Audit%20Report.pdf" + }, + { + "title": "It is possible to vote during the objection time if the proposal was rejected", + "content": "##### Description\nAt line https://github.com/lidofinance/aragon-apps/blob/7e5cd1961697a1bc514bfebdeab08a296e51d700/apps/voting/contracts/Voting.sol#L192 during the objection time, the `vote()` function checks if the vote is `no`, if the vote is open for objection and if the voter has balance. But there is no check wether the vote was rejected or not. So it is possible to vote `no` for a proposal even if it was rejected during the voting time.\n\n##### Recommendation\nIt is recommended to add a check if the vote was rejected.\n", + "protocol": "Lido", + "report_date": "2022-06-20", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Two-Phase%20Voting/README.md#1-it-is-possible-to-vote-during-the-objection-time-if-the-proposal-was-rejected", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Two-Phase%20Voting/Lido%20Two-Phase%20Voting%20Security%20Audit%20Report.pdf" + }, + { + "title": "Using unsuitable visibility modifier", + "content": "##### Description\nThe visibility of the `canObject()` function at line https://github.com/lidofinance/aragon-apps/blob/7e5cd1961697a1bc514bfebdeab08a296e51d700/apps/voting/contracts/Voting.sol#L267 which is not called internally from the same contract should be changed to `external` to save gas.\n\n##### Recommendation\nIt is recommended to change `public` to `external`.\n", + "protocol": "Lido", + "report_date": "2022-06-20", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Two-Phase%20Voting/README.md#1-using-unsuitable-visibility-modifier", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Two-Phase%20Voting/Lido%20Two-Phase%20Voting%20Security%20Audit%20Report.pdf" + }, + { + "title": "The vote is open for objection during the main voting time", + "content": "##### Description\nAt line https://github.com/lidofinance/aragon-apps/blob/7e5cd1961697a1bc514bfebdeab08a296e51d700/apps/voting/contracts/Voting.sol#L475\nthe `_isVoteOpenForObjection()` function returns `true` during the main voting time. It can be potentially misleading in functions `canObject()` and `getVote()` at the following lines:\n- https://github.com/lidofinance/aragon-apps/blob/7e5cd1961697a1bc514bfebdeab08a296e51d700/apps/voting/contracts/Voting.sol#L267\n- https://github.com/lidofinance/aragon-apps/blob/7e5cd1961697a1bc514bfebdeab08a296e51d700/apps/voting/contracts/Voting.sol#L316.\n\n##### Recommendation\nIt is recommended to change the `_isVoteOpenForObjection()` function to return `true` only during the objection time or to rename the function to better indicate its purpose.\n", + "protocol": "Lido", + "report_date": "2022-06-20", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Two-Phase%20Voting/README.md#2-the-vote-is-open-for-objection-during-the-main-voting-time", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Two-Phase%20Voting/Lido%20Two-Phase%20Voting%20Security%20Audit%20Report.pdf" + }, + { + "title": "Double check of the `_supports` variable", + "content": "##### Description\nAt line https://github.com/lidofinance/aragon-apps/blob/7e5cd1961697a1bc514bfebdeab08a296e51d700/apps/voting/contracts/Voting.sol#L374-L380 there is a double check of variable `_supports`.\n\nThe assignment at line https://github.com/lidofinance/aragon-apps/blob/7e5cd1961697a1bc514bfebdeab08a296e51d700/apps/voting/contracts/Voting.sol#L380 can be moved inside the if-else statement to save gas. Additionally, the if-else statement is more readable than a ternary operator.\n\n##### Recommendation\nIt is recommended to change to:\n```solidity\nif (_supports) {\n vote_.yea = vote_.yea.add(voterStake);\n vote_.voters[_voter] = VoterState.Yea;\n} else {\n vote_.nay = vote_.nay.add(voterStake);\n vote_.voters[_voter] = VoterState.Nay;\n}\n```\n", + "protocol": "Lido", + "report_date": "2022-06-20", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Two-Phase%20Voting/README.md#3-double-check-of-the-_supports-variable", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Two-Phase%20Voting/Lido%20Two-Phase%20Voting%20Security%20Audit%20Report.pdf" + }, + { + "title": "Unnecessary check", + "content": "##### Description\nAt line https://github.com/lidofinance/aragon-apps/blob/7e5cd1961697a1bc514bfebdeab08a296e51d700/apps/voting/contracts/Voting.sol#L423 the check is unnecessary since the check at line https://github.com/lidofinance/aragon-apps/blob/7e5cd1961697a1bc514bfebdeab08a296e51d700/apps/voting/contracts/Voting.sol#L428 returns `true` if the vote is open during the voting time. The vote cannot be executed until the end of the objection time.\n\n##### Recommendation\nRemove this check or refactor the `_isVoteOpen()` and `_isVoteOpenForObjection()` logic.\n", + "protocol": "Lido", + "report_date": "2022-06-20", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Two-Phase%20Voting/README.md#4-unnecessary-check", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Two-Phase%20Voting/Lido%20Two-Phase%20Voting%20Security%20Audit%20Report.pdf" + }, + { + "title": "Gas optimization using `vote_.yea`", + "content": "##### Description\nAt line https://github.com/lidofinance/aragon-apps/blob/7e5cd1961697a1bc514bfebdeab08a296e51d700/apps/voting/contracts/Voting.sol#L433-L440 it is possible to save gas by reading `vote_.yea` into a memory variable.\n\n##### Recommendation\nFor example:\n```solidity\nuint256 voteYea = vote_.yea;\nuint256 totalVotes = voteYea.add(vote_.nay);\nif (!_isValuePct(voteYea, totalVotes, vote_.supportRequiredPct)) {\n return false;\n}\n// Has min quorum?\nif (!_isValuePct(voteYea, vote_.votingPower, vote_.minAcceptQuorumPct)) {\n return false;\n}\n```\n", + "protocol": "Lido", + "report_date": "2022-06-20", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Two-Phase%20Voting/README.md#5-gas-optimization-using-vote_yea", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Two-Phase%20Voting/Lido%20Two-Phase%20Voting%20Security%20Audit%20Report.pdf" + }, + { + "title": "A malicious voter can potentially block a vote", + "content": "##### Description\nAt line https://github.com/lidofinance/aragon-apps/blob/7e5cd1961697a1bc514bfebdeab08a296e51d700/apps/voting/contracts/Voting.sol#L368 a voter can change their vote.\nThe malicious voter can initially vote `yes` misleading other users about their intention, then change their vote to `no` at the last moment potentially blocking the proposal.\n\n##### Recommendation\nIt is recommended to check to prevent the last-minute `no` attacks against proposals.\n", + "protocol": "Lido", + "report_date": "2022-06-20", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Two-Phase%20Voting/README.md#6-a-malicious-voter-can-potentially-block-a-vote", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Two-Phase%20Voting/Lido%20Two-Phase%20Voting%20Security%20Audit%20Report.pdf" + }, + { + "title": "Confusing naming can lead to vulnerabilities in the future code edits", + "content": "##### Description\n\nA voting passes two stages: \n1. Vote is open for yeas and nays\n2. Vote is open for nays only\n\nTo check for those stages these methods are used:\n1. `_isVoteOpen`, `_canVote`, `canVote`\n2. `_isVoteOpenForObjection`, `_canObject`, `canObject`\n\nNamings to check that the voting is in the first stage are confusing, because name `_isVoteOpen` doesn't clearly say that it is checking the first stage only and for the second stage of voting it will return `false`. The same thing refers to `canVote()` and `_canVote()`. Their names suggest that they should return `true` for any unfinished voting, while they return `true` only if the voting is in the first stage.\n\nThis confusion may lead to bugs in the future if the contract code base becomes larger and it will become harder to keep in mind that the behavior of some methods differs from what their name seems to imply.\n\nThere are already cases of the incorrect use of methods in the code:\nhttps://github.com/lidofinance/aragon-apps/blob/7e5cd1961697a1bc514bfebdeab08a296e51d700/apps/voting/contracts/Voting.sol#L384\n```solidity\nfunction _vote(uint256 _voteId, bool _supports, address _voter) internal {\n ...\n if (!_isVoteOpen(vote_)) { // objection phase\n ...\n emit CastObjection(_voteId, _voter, voterStake);\n}\n```\nIt is obvious that instead of `!_isVoteOpen(vote_)` you should use `_isVoteOpenForObjection(vote_)`. It is not a vulnerability now because in the current context these two lines are interchangeble.\n\nHowever, if in the future the development team decides to add another voting phase, they will have to find and fix all the lines with the incorrect use of methods and if the code base becomes large and the namings would be still confusing it will be easy to miss some line and create a vulnerability.\n\n\n##### Recommendation\n\nChange method names to be more clear about what they really do. For example, instead of `_isVoteOpen` you could use `_isVoteOpenFirstStage`. And instead of `_canVote` you could use `_canVoteFirstStage`.\n\nThe `canVote` method is a public method so it may be better to keep its name for API compatibility. But perhabs it should be marked as deprecated in the code comments and another,`canVoteFirstStage` method should be added.\n", + "protocol": "Lido", + "report_date": "2022-06-20", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Two-Phase%20Voting/README.md#7-confusing-naming-can-lead-to-vulnerabilities-in-the-future-code-edits", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Two-Phase%20Voting/Lido%20Two-Phase%20Voting%20Security%20Audit%20Report.pdf" + }, + { + "title": "Missed NatSpec parameters descriptions for public methods", + "content": "##### Description\nhttps://github.com/lidofinance/aragon-apps/blob/7e5cd1961697a1bc514bfebdeab08a296e51d700/apps/voting/contracts/Voting.sol#L234\nhttps://github.com/lidofinance/aragon-apps/blob/7e5cd1961697a1bc514bfebdeab08a296e51d700/apps/voting/contracts/Voting.sol#L247\nhttps://github.com/lidofinance/aragon-apps/blob/7e5cd1961697a1bc514bfebdeab08a296e51d700/apps/voting/contracts/Voting.sol#L257\nhttps://github.com/lidofinance/aragon-apps/blob/7e5cd1961697a1bc514bfebdeab08a296e51d700/apps/voting/contracts/Voting.sol#L267\nhttps://github.com/lidofinance/aragon-apps/blob/7e5cd1961697a1bc514bfebdeab08a296e51d700/apps/voting/contracts/Voting.sol#L324\n\n##### Recommendation\nWe recommend adding descriptions for the mentioned public methods parameters.\n", + "protocol": "Lido", + "report_date": "2022-06-20", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Two-Phase%20Voting/README.md#8-missed-natspec-parameters-descriptions-for-public-methods", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Two-Phase%20Voting/Lido%20Two-Phase%20Voting%20Security%20Audit%20Report.pdf" + }, + { + "title": "The \"last-minute\" vote problem still persists for vote objection", + "content": "##### Description\nThe problem with the \"last-minute\" vote in this scheme is not fully mitigated, because a possibility of a vote to be denied at the last moment still persists. An attacker can object and deny the voting at the last moment like it could be done with the previous version of voting.\n\n##### Recommendation\nShould be simply acknowledged by the Lido team.\n", + "protocol": "Lido", + "report_date": "2022-06-20", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Two-Phase%20Voting/README.md#9-the-last-minute-vote-problem-still-persists-for-vote-objection", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Two-Phase%20Voting/Lido%20Two-Phase%20Voting%20Security%20Audit%20Report.pdf" + }, + { + "title": "Reward tokens may be frozen in `FarmingPool`", + "content": "##### Description\nhttps://github.com/1inch/farming/blob/7a007ec7784cca2899889e99e46cf06d5788a7d9/contracts/accounting/FarmAccounting.sol#L19\nFarmed tokens amount is calculated when a farm duration > 0, so if the distributor starts farming with duration 0, nobody will farm and, starting the next farming, won't save prev farming rewards because a contract accounts only unfinished prev farming, but in this case the farming with duration 0 finishes immediately.\nhttps://github.com/1inch/farming/blob/7a007ec7784cca2899889e99e46cf06d5788a7d9/contracts/accounting/FarmAccounting.sol#L28\n##### Recommendation\nWe recommend not to allow farming with 0 duration.\n\n***\n", + "protocol": "1inch", + "report_date": "2022-06-01", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Farming/README.md#1-reward-tokens-may-be-frozen-in-farmingpool", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Farming/1Inch%20Farming%20Security%20Audit%20Report.pdf" + }, + { + "title": "Actual transferred amount may differ than expected", + "content": "##### Description\nSome ERC20 tokens, for example, USDT, have fees on transfer. It may affect reward accounting on farming, a farm contract may receive fewer tokens than expected and start farming with an expected amount of rewards, which will lead to insufficiency of liquidity for rewards. Also in the`FarmingPool` contract the `deposit` and `withdraw` functions may work incorrectly. \nhttps://github.com/1inch/farming/blob/7a007ec7784cca2899889e99e46cf06d5788a7d9/contracts/Farm.sol#L41-L43, \nhttps://github.com/1inch/farming/blob/7a007ec7784cca2899889e99e46cf06d5788a7d9/contracts/FarmingPool.sol#L48-L50\n##### Recommendation\nWe recommend starting farming/deposit in `FarmingPool`/withdraw in `FarmingPool` with the actual transferred amount and return an actual deposited/withdrawn/claimed amount.\n", + "protocol": "1inch", + "report_date": "2022-06-01", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Farming/README.md#2-actual-transferred-amount-may-differ-than-expected", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Farming/1Inch%20Farming%20Security%20Audit%20Report.pdf" + }, + { + "title": "Rebasable as reward tokens breaks logic", + "content": "##### Description\nWith rebasable reward tokens, the calculation of farmed rewards will be incorrect because it relies on a strict amount of distributed tokens while the underlying reward balance will float. \nhttps://github.com/1inch/farming/blob/7a007ec7784cca2899889e99e46cf06d5788a7d9/contracts/accounting/FarmAccounting.sol#L21\n##### Recommendation\nWe recommend warning developers not to use rebasable tokens as reward tokens.\n", + "protocol": "1inch", + "report_date": "2022-06-01", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Farming/README.md#3-rebasable-as-reward-tokens-breaks-logic", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Farming/1Inch%20Farming%20Security%20Audit%20Report.pdf" + }, + { + "title": "Possible arithmetic overflow", + "content": "##### Description\nAt the line https://github.com/1inch/farming/blob/7a007ec7784cca2899889e99e46cf06d5788a7d9/contracts/accounting/UserAccounting.sol#L29 the number with the type `int256` is converted to the number with the type `uint256`. The number is taken with a minus sign.\nBut before that, there is no check that the number is less than 0.\nIf we take a small positive value and apply the transformation `uint256(-amount)` to it, we get a very large value due to arithmetic overflow.\nFor example, if you take number `1000`, then after conversion you get value` 115792089237316195423570985008687907853269984665640564039457584007913129638936`.\n\n##### Recommendation\nBefore line 29 you need to check if the value of the variable is not less than 0.\n If the value of the variable is positive, then do not do the conversion.\n\n", + "protocol": "1inch", + "report_date": "2022-06-01", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Farming/README.md#1-possible-arithmetic-overflow", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Farming/1Inch%20Farming%20Security%20Audit%20Report.pdf" + }, + { + "title": "Gas overflow during iteration (DoS)", + "content": "##### Description\nEach iteration of the cycle requires a gas flow.\nA moment may come when more gas is required than it is allocated to record one block. In this case, all iterations of the loop will fail.\nAffected lines:\n- https://github.com/1inch/farming/blob/7a007ec7784cca2899889e99e46cf06d5788a7d9/contracts/ERC20Farmable.sol#L70\n- https://github.com/1inch/farming/blob/7a007ec7784cca2899889e99e46cf06d5788a7d9/contracts/ERC20Farmable.sol#L117\n- https://github.com/1inch/farming/blob/7a007ec7784cca2899889e99e46cf06d5788a7d9/contracts/ERC20Farmable.sol#L121\n- https://github.com/1inch/farming/blob/7a007ec7784cca2899889e99e46cf06d5788a7d9/contracts/ERC20Farmable.sol#L137\n##### Recommendation\nIt is recommended to add a check for the maximum possible number of elements of the arrays.\n\n***\n", + "protocol": "1inch", + "report_date": "2022-06-01", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Farming/README.md#2-gas-overflow-during-iteration-dos", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Farming/1Inch%20Farming%20Security%20Audit%20Report.pdf" + }, + { + "title": "Zero Token", + "content": "##### Description\nThere is no address checking for tokens params in constructor:\nhttps://github.com/1inch/farming/blob/7a007ec7784cca2899889e99e46cf06d5788a7d9/contracts/FarmingPool.sol#L35-L36\n##### Recommendation\nIt is recommended to add a check for non-zero address.\n\n***\n", + "protocol": "1inch", + "report_date": "2022-06-01", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Farming/README.md#3-zero-token", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Farming/1Inch%20Farming%20Security%20Audit%20Report.pdf" + }, + { + "title": "Using \"magic\" numbers", + "content": "##### Description\nThe use in the source code of some unknown where taken values impairs its understanding.\nAt the lines\n- https://github.com/1inch/farming/blob/7a007ec7784cca2899889e99e46cf06d5788a7d9/contracts/accounting/FarmAccounting.sol#L21\n- https://github.com/1inch/farming/blob/7a007ec7784cca2899889e99e46cf06d5788a7d9/contracts/accounting/FarmAccounting.sol#L29\n- https://github.com/1inch/farming/blob/7a007ec7784cca2899889e99e46cf06d5788a7d9/contracts/accounting/UserAccounting.sol#L29\nthe value is `1e18`.\n##### Recommendation\nIt is recommended that you create constants with meaningful names to use numeric values.\n\n***\n", + "protocol": "1inch", + "report_date": "2022-06-01", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Farming/README.md#1-using-magic-numbers", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Farming/1Inch%20Farming%20Security%20Audit%20Report.pdf" + }, + { + "title": "It is possible to block tokens on the balance of the contract", + "content": "##### Description\nAt the line https://github.com/1inch/farming/blob/7a007ec7784cca2899889e99e46cf06d5788a7d9/contracts/FarmingPool.sol#L48 `rewardsToken` is transferred to the balance of the contract.\nBut there is no functionality to return tokens in case of an emergency or if not all users call the `claim()` function.\n##### Recommendation\nIt is necessary to add functionality for the possibility of withdrawing the remaining tokens from the balance of the contract.\n\n***\n", + "protocol": "1inch", + "report_date": "2022-06-01", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Farming/README.md#2-it-is-possible-to-block-tokens-on-the-balance-of-the-contract", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Farming/1Inch%20Farming%20Security%20Audit%20Report.pdf" + }, + { + "title": "Missed events", + "content": "##### Description\nThere are missed events for claim, deposit, withdraw, join/quit farming.\nhttps://github.com/1inch/farming/blob/7a007ec7784cca2899889e99e46cf06d5788a7d9/contracts/FarmingPool.sol#L66\nhttps://github.com/1inch/farming/blob/7a007ec7784cca2899889e99e46cf06d5788a7d9/contracts/FarmingPool.sol#L72\nhttps://github.com/1inch/farming/blob/7a007ec7784cca2899889e99e46cf06d5788a7d9/contracts/FarmingPool.sol#L78\nhttps://github.com/1inch/farming/blob/7a007ec7784cca2899889e99e46cf06d5788a7d9/contracts/ERC20Farmable.sol#L58\nhttps://github.com/1inch/farming/blob/7a007ec7784cca2899889e99e46cf06d5788a7d9/contracts/ERC20Farmable.sol#L75\nhttps://github.com/1inch/farming/blob/7a007ec7784cca2899889e99e46cf06d5788a7d9/contracts/ERC20Farmable.sol#L93\n##### Recommendation\nWe recommend emitting the events above.\n\n***\n", + "protocol": "1inch", + "report_date": "2022-06-01", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Farming/README.md#3-missed-events", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Farming/1Inch%20Farming%20Security%20Audit%20Report.pdf" + }, + { + "title": "Opportunity to add bufferedETH without submitting to LIDO", + "content": "##### Description\nIt is possible to send ETH to the `LidoMevTxFeeVault` contract and when the oracle reports contract sends ETH to LIDO, which will be used to rewards, it may fluctuate the price of lido shares.\nhttps://github.com/lidofinance/lido-dao/blob/801d3e854efb33ff33a59fe51187e187047a6be2/contracts/0.8.9/LidoMevTxFeeVault.sol#L79\n##### Recommendation\nWe recommend that the `LidoMevTxFreeVault` contract should receive ETH only from authorized addresses or the `withdrawRewards()` function should have limits.\n", + "protocol": "Lido", + "report_date": "2022-05-24", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20Protocol/README.md#1-opportunity-to-add-bufferedeth-without-submitting-to-lido", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20Protocol/Lido%20Protocol%20Security%20Audit%20Report.pdf" + }, + { + "title": "Extra function", + "content": "##### Description\nAt lines\nhttps://github.com/lidofinance/lido-dao/blob/801d3e854efb33ff33a59fe51187e187047a6be2/contracts/0.4.24/Lido.sol#L139-L142\nand at lines\nhttps://github.com/lidofinance/lido-dao/blob/801d3e854efb33ff33a59fe51187e187047a6be2/contracts/0.4.24/Lido.sol#L158-L165\nsimilar actions are performed.\nBut in one case there is a change in the `TOTAL_MEV_TX_FEE_COLLECTED_POSITION` variable, and in the other case there is none.\nOne of these functions is redundant.\n##### Recommendation\nNeed to remove the redundant feature.", + "protocol": "Lido", + "report_date": "2022-05-24", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20Protocol/README.md#1-extra-function", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20Protocol/Lido%20Protocol%20Security%20Audit%20Report.pdf" + }, + { + "title": "No validation of the address parameter value in the contract constructor", + "content": "##### Description\nThe variable is assigned the value of the constructor input parameter. But this parameter is not checked before this. If the value turns out to be zero, then it will be necessary to redeploy the contract, since there is no other functionality to set this variable.\nAt line \nhttps://github.com/lidofinance/lido-dao/blob/801d3e854efb33ff33a59fe51187e187047a6be2/contracts/0.8.9/LidoMevTxFeeVault.sol#L72 \nthe `TREASURY` variable is set to the value of the `_treasury` input parameter.\n##### Recommendation\nIt is necessary to add a check of the input parameter to zero before initializing the variable.", + "protocol": "Lido", + "report_date": "2022-05-24", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20Protocol/README.md#2-no-validation-of-the-address-parameter-value-in-the-contract-constructor", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20Protocol/Lido%20Protocol%20Security%20Audit%20Report.pdf" + }, + { + "title": "Max oracle members amount is actually lower", + "content": "##### Description\nMax members are 255 instead of 256 which may affect the quorum:\nhttps://github.com/lidofinance/lido-dao/blob/801d3e854efb33ff33a59fe51187e187047a6be2/contracts/0.4.24/oracle/LidoOracle.sol#L432\n##### Recommendation\nThe check needs to be corrected.", + "protocol": "Lido", + "report_date": "2022-05-24", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20Protocol/README.md#3-max-oracle-members-amount-is-actually-lower", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20Protocol/Lido%20Protocol%20Security%20Audit%20Report.pdf" + }, + { + "title": "There is no recovery option for ERC721", + "content": "##### Description\nThe `transferToVault()` function doesn't support ERC721 tokens: \nhttps://github.com/lidofinance/lido-dao/blob/801d3e854efb33ff33a59fe51187e187047a6be2/contracts/0.4.24/Lido.sol#L356\n##### Recommendation\nIt is necessary to add another function to recover ERC721.", + "protocol": "Lido", + "report_date": "2022-05-24", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20Protocol/README.md#4-there-is-no-recovery-option-for-erc721", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20Protocol/Lido%20Protocol%20Security%20Audit%20Report.pdf" + }, + { + "title": "Incorrect event", + "content": "##### Description\nIn case of cover, `stETH` doesn't burn \nhttps://github.com/lidofinance/lido-dao/blob/801d3e854efb33ff33a59fe51187e187047a6be2/contracts/0.4.24/StETH.sol#L461\n##### Recommendation\nIt is necessary to exclude the `stETH` amount from the event.", + "protocol": "Lido", + "report_date": "2022-05-24", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20Protocol/README.md#5-incorrect-event", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20Protocol/Lido%20Protocol%20Security%20Audit%20Report.pdf" + }, + { + "title": "There is no recovery for excess `stETH`", + "content": "##### Description\nIt is possible to transfer `stETH` to `wstETH` so it will be frozen in the contract. \nhttps://github.com/lidofinance/lido-dao/blob/801d3e854efb33ff33a59fe51187e187047a6be2/contracts/0.6.12/WstETH.sol#L28-L118\n##### Recommendation\nIt is necessary to add a function to recover excess `stETH` and keep the wrapped shares amount.", + "protocol": "Lido", + "report_date": "2022-05-24", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20Protocol/README.md#6-there-is-no-recovery-for-excess-steth", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20Protocol/Lido%20Protocol%20Security%20Audit%20Report.pdf" + }, + { + "title": "Callback verification", + "content": "##### Description\nBy mistake a callback which has no implementation of the`processLidoOracleReport()` method can be added at the line:\nhttps://github.com/lidofinance/lido-dao/blob/801d3e854efb33ff33a59fe51187e187047a6be2/contracts/0.8.9/OrderedCallbacksArray.sol#L60\nIn case you set the `IBeaconReportReceiver` address, the execution of the following lines will be reverted.\nhttps://github.com/lidofinance/lido-dao/blob/801d3e854efb33ff33a59fe51187e187047a6be2/contracts/0.4.24/oracle/LidoOracle.sol#L644\n##### Recommendation\nIt is necessary to add verification of the existing `processLidoOracleReport()` method in callback or callbacks should be double-checked before adding.\nSee this standard: https://eips.ethereum.org/EIPS/eip-165.", + "protocol": "Lido", + "report_date": "2022-05-24", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20Protocol/README.md#7-callback-verification", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20Protocol/Lido%20Protocol%20Security%20Audit%20Report.pdf" + }, + { + "title": "No check before initialization", + "content": "##### Description\nAt the lines\nhttps://github.com/lidofinance/lido-dao/blob/801d3e854efb33ff33a59fe51187e187047a6be2/contracts/0.4.24/Lido.sol#L339-L340\nIf the value of variable `mevRewards` is equal to 0, then the initialization of variable `BUFFERED_ETHER_POSITION` will still be performed. This will also require gas consumption.\n##### Recommendation\nIt is recommended to add a check before initialization.", + "protocol": "Lido", + "report_date": "2022-05-24", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20Protocol/README.md#1-no-check-before-initialization", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20Protocol/Lido%20Protocol%20Security%20Audit%20Report.pdf" + }, + { + "title": "No comparison with previous value", + "content": "##### Description\nAt line\nhttps://github.com/lidofinance/lido-dao/blob/801d3e854efb33ff33a59fe51187e187047a6be2/contracts/0.8.9/DepositSecurityModule.sol#L204\nthe variable is initialized. But if the new value is equal to the old value, the excess gas will be wasted.\n##### Recommendation\nIt is recommended to add a check before initializing the variable.", + "protocol": "Lido", + "report_date": "2022-05-24", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20Protocol/README.md#2-no-comparison-with-previous-value", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20Protocol/Lido%20Protocol%20Security%20Audit%20Report.pdf" + }, + { + "title": "A comment about the node operator count", + "content": "##### Description\nThere is a comment about the node operator count but there is no functionality related to it at the line:\nhttps://github.com/lidofinance/lido-dao/blob/801d3e854efb33ff33a59fe51187e187047a6be2/contracts/0.4.24/nos/NodeOperatorsRegistry.sol#L23\nOnly manual moderating is available.\n##### Recommendation\nIt is recommended to add a check for the maximum number of operators when adding new ones.", + "protocol": "Lido", + "report_date": "2022-05-24", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20Protocol/README.md#3-a-comment-about-the-node-operator-count", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20Protocol/Lido%20Protocol%20Security%20Audit%20Report.pdf" + }, + { + "title": "Not all params are there at the comment", + "content": "##### Description\nAfter line\nhttps://github.com/lidofinance/lido-dao/blob/801d3e854efb33ff33a59fe51187e187047a6be2/contracts/0.4.24/Lido.sol#L97\na description of the two parameters `_treasury` and `_insuranceFund` must be added.\n##### Recommendation\nIt is recommended to fix the code.", + "protocol": "Lido", + "report_date": "2022-05-24", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20Protocol/README.md#4-not-all-params-are-there-at-the-comment", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20Protocol/Lido%20Protocol%20Security%20Audit%20Report.pdf" + }, + { + "title": "Code inconsistency", + "content": "##### Description\nThe address above is not cast to address \nhttps://github.com/lidofinance/lido-dao/blob/801d3e854efb33ff33a59fe51187e187047a6be2/contracts/0.4.24/Lido.sol#L111.\n##### Recommendation\nIt is recommended to fix the code.", + "protocol": "Lido", + "report_date": "2022-05-24", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20Protocol/README.md#5-code-inconsistency", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20Protocol/Lido%20Protocol%20Security%20Audit%20Report.pdf" + }, + { + "title": "Typo mistake", + "content": "##### Description\nIt should be `stored` \nhttps://github.com/lidofinance/lido-dao/blob/801d3e854efb33ff33a59fe51187e187047a6be2/contracts/0.4.24/oracle/LidoOracle.sol#L78\n##### Recommendation\nIt is recommended to fix the code.", + "protocol": "Lido", + "report_date": "2022-05-24", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20Protocol/README.md#6-typo-mistake", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20Protocol/Lido%20Protocol%20Security%20Audit%20Report.pdf" + }, + { + "title": "Using `transferShares()` is possible", + "content": "##### Description\nTransfer can be made via `transferShares()`: \nhttps://github.com/lidofinance/lido-dao/blob/801d3e854efb33ff33a59fe51187e187047a6be2/contracts/0.6.12/WstETH.sol#L73\n##### Recommendation\nIt is recommended to fix the code.", + "protocol": "Lido", + "report_date": "2022-05-24", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20Protocol/README.md#7-using-transfershares-is-possible", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20Protocol/Lido%20Protocol%20Security%20Audit%20Report.pdf" + }, + { + "title": "Spoofed initial deposits in `SexPartners.sol` and `LpDepositor.sol`", + "content": "##### Description\nThe **initial** deposit of NFT is vulnerable to a spoofing attack.\nThe attacker can directly call `onERC721Received` and supply NFT id that was not actually transferred/not owned by the attacker. It may cause a contract malfunction, including contract unusability or incorrect calculation of the rewards. A contract malfunction cannot be fixed without a contract replacement.\n\nPlease note, this attack can only affect a contract at the initial stage, before the initial deposit was made. Spoofing attempts for any deposits except the initial deposit will be reverted or will not change the state of the contract. Thus a contract at the production stage (after the initial deposit) is not vulnerable anymore.\n\n\nLocation of the affected code:\n- https://github.com/solidex-fantom/solidex/blob/8b420ed8bed4b714695d51de2a0f82e38a72e1b2/contracts/SexPartners.sol#L95\n- https://github.com/solidex-fantom/solidex/blob/8b420ed8bed4b714695d51de2a0f82e38a72e1b2/contracts/LpDepositor.sol#L351\n##### Recommendation\nAlthough an attack can be easily detected and mitigated by redeploying of the contracts, we recommend to add explicit checks for the known attack vector.\n", + "protocol": "Solidex", + "report_date": "2022-03-21", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Solidex/Solidex/README.md#1-spoofed-initial-deposits-in-sexpartnerssol-and-lpdepositorsol", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Solidex/Solidex/Solidex-Security-Audit-Report.pdf" + }, + { + "title": "Possible blocking of the contract", + "content": "##### Description\nAt the line \nhttps://github.com/lidofinance/lido-dao/blob/5b449b740cddfbef5c107505677e6a576e2c2b69/contracts/0.8.9/DepositSecurityModule.sol#L123 \ninitializes the `owner` variable without checking the new value of the variable.\nIf the value of the variable is equal to zero, then the following functions will stop working:\n`setOwner()`, `setNodeOperatorsRegistry()`, `setPauseIntentValidityPeriodBlocks()`, `setMaxDeposits()`,\n`setMinDepositBlockDistance()`, `setGuardianQuorum()`, `addGuardian()`, `addGuardians()`, `removeGuardian()`, `unpauseDeposits()`.\n##### Recommendation\nIt is necessary to add a check for the value of the `newValue` variable to zero before initializing the `owner` variable.", + "protocol": "Lido", + "report_date": "2022-02-28", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Deposit%20Security%20Module/README.md#1-possible-blocking-of-the-contract", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Deposit%20Security%20Module/Lido%20Deposit%20Security%20Module%20Security%20Audit%20Report.pdf" + }, + { + "title": "Fix gas cost ETH transfer", + "content": "##### Description\nETH sending at this line \nhttps://github.com/lidofinance/lido-dao/blob/5b449b740cddfbef5c107505677e6a576e2c2b69/contracts/0.4.24/Lido.sol#L301 \nuses 2300 gas amount, but gas price can be vary and it is possible that in future it may exceed gas limit.\n##### Recommendation\nWe recommend sending ETH via call.", + "protocol": "Lido", + "report_date": "2022-02-28", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Deposit%20Security%20Module/README.md#2-fix-gas-cost-eth-transfer", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Deposit%20Security%20Module/Lido%20Deposit%20Security%20Module%20Security%20Audit%20Report.pdf" + }, + { + "title": "Possibility of taking burned shares", + "content": "##### Description\nWith attack it is possible to take burned shares profit even without taking shares before `processLidoOracleReport()` execution.\nhttps://github.com/lidofinance/lido-dao/blob/ee1991b3bbea2a24b042b0a4433be04301992656/contracts/0.8.9/SelfOwnedStETHBurner.sol#L252\nThis exploit shows how the attack is done:\nhttps://gist.github.com/georgiypetrov/22c0649058a97102e2fd97a1c619a3b3\nIf this is a front-run attack, then it will be the most convenient for the attacker.\n##### Recommendation\nIt is necessary to add a limit on the amount of burned tokens.", + "protocol": "Lido", + "report_date": "2022-02-28", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/In-protocol%20Coverage/README.md#1-possibility-of-taking-burned-shares", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/In-protocol%20Coverage/Lido%20In-protocol%20%20Coverage%20Security%20Audit%20Report.pdf" + }, + { + "title": "Security and sanity check bypass in `MultiCallOptimizedSwapper`", + "content": "##### Description\nAs well as similar functions, [`execute`](https://github.com/yearn/hardhat-monorepo/blob/ecc0b5147992b34c315e08af170ceb4a5fe071ee/packages/yswaps/contracts/TradeFactory/TradeFactoryExecutor.sol#L126) performs several sanity and security checks:\n- provided swapper is required to be in `_swappers` enumerable set\n- exchange path `tokenIn` and `tokenOut` is required to be enabled for given `strategy`\n- output token amount is required to be greater or equal to provided `minAmountOut`.\n\nHowever, the actual code executed by [`_executeSwap`](https://github.com/yearn/hardhat-monorepo/blob/ecc0b5147992b34c315e08af170ceb4a5fe071ee/packages/yswaps/contracts/swappers/async/MultiCallOptimizedSwapper.sol#L27) is arbitrary and can accidentally or intentionally bypass these checks. Although `MultiCallOptimizedSwapper` can be only invoked by the trusted actor `onlyMechanics`, arbitrary code execution can probably lead to loss of funds in case of accidental bug at off-chain bot. Also, single compromised `Mechanic` account key can lead to \"rug pull\" from all connected strategies.\n##### Recommendation\nWe recommend to disallow execution of arbitrary code and keep the best practice of white-listing of allowed actions and calls, similar to other swappers at `contracts/swappers/async` directory.", + "protocol": "Yearn Finance", + "report_date": "2022-02-28", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/ySwaps/README.md#1-security-and-sanity-check-bypass-in-multicalloptimizedswapper", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/ySwaps/Yearn%20ySwaps%20Security%20Audit%20Report.pdf" + }, + { + "title": "Unnecessary and unrestricted `trade()` at `sync/BancorSwapper`", + "content": "##### Description\n[trade()](https://github.com/yearn/hardhat-monorepo/blob/ecc0b5147992b34c315e08af170ceb4a5fe071ee/packages/yswaps/contracts/swappers/sync/BancorSwapper.sol#L52) function has no use and most likely remains in contract by an accident. However, it is unrestricted and can be called by anyone. \n##### Recommendation\nAlthough we have not found any attack vector for this issue, we recommend to remove this code to improve security.\n", + "protocol": "Yearn Finance", + "report_date": "2022-02-28", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/ySwaps/README.md#2-unnecessary-and-unrestricted-trade-at-syncbancorswapper", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/ySwaps/Yearn%20ySwaps%20Security%20Audit%20Report.pdf" + }, + { + "title": "Incompatibility with fee-on-transfer tokens", + "content": "##### Description\nSeveral parts of code have assumption that `transferFrom(..., amount)` will result in receiving of exact `amount` of tokens:\n\n- https://github.com/yearn/hardhat-monorepo/blob/ecc0b5147992b34c315e08af170ceb4a5fe071ee/packages/yswaps/contracts/TradeFactory/TradeFactoryExecutor.sol#L82-L88\n- https://github.com/yearn/hardhat-monorepo/blob/ecc0b5147992b34c315e08af170ceb4a5fe071ee/packages/yswaps/contracts/TradeFactory/TradeFactoryExecutor.sol#L111-L117\n\nHowever, actual amount of received tokens can be less for fee-on-transfer tokens.\n##### Recommendation\nFor compatibility with fee-on-transfer tokens we recommend to use `balanceOf` to obtain actual amounts of tokens received by `transferFrom`. ", + "protocol": "Yearn Finance", + "report_date": "2022-02-28", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/ySwaps/README.md#3-incompatibility-with-fee-on-transfer-tokens", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/ySwaps/Yearn%20ySwaps%20Security%20Audit%20Report.pdf" + }, + { + "title": "Incorrect slippage check", + "content": "##### Description\nCondition in slippage check is logically reversed: \nhttps://github.com/yearn/hardhat-monorepo/blob/ecc0b5147992b34c315e08af170ceb4a5fe071ee/packages/yswaps/contracts/TradeFactory/TradeFactoryExecutor.sol#L150\n##### Recommendation\nNote: this issue was found by the developers\n\n***\n", + "protocol": "Yearn Finance", + "report_date": "2022-02-28", + "impact": "MEDIUM", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/ySwaps/README.md#4-incorrect-slippage-check", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/ySwaps/Yearn%20ySwaps%20Security%20Audit%20Report.pdf" + }, + { + "title": "Unrestricted setter in `Machinery` contract", + "content": "##### Description\nSetter for the mechanics registry [setMechanicsRegistry](https://github.com/yearn/hardhat-monorepo/blob/ecc0b5147992b34c315e08af170ceb4a5fe071ee/packages/contract-utils/contracts/utils/Machinery.sol#L22) has no access restriction. It can cause security breach in inherited contracts that lack security-aware override of `setMechanicsRegistry` function.\n##### Recommendation\nAlthough currently all of the inherited contracts from audited scope override `setMechanicsRegistry` properly, we recommend to prevent accidental inheritance of insecure code by modifying or removing `setMechanicsRegistry` function from `Machinery` contract. Additionally, this contract is most likely has been planned to be `abstract`.", + "protocol": "Yearn Finance", + "report_date": "2022-02-28", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/ySwaps/README.md#1-unrestricted-setter-in-machinery-contract", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/ySwaps/Yearn%20ySwaps%20Security%20Audit%20Report.pdf" + }, + { + "title": "Unnecessary assembly in `MultiCallOptimizedSwapper.sol`", + "content": "##### Description\n[MultiCallOptimizer.sol](https://github.com/yearn/hardhat-monorepo/blob/ecc0b5147992b34c315e08af170ceb4a5fe071ee/packages/yswaps/contracts/swappers/async/MultiCallOptimizedSwapper.sol) contract is using assembly most likely for gas optimization purposes. However, this approach does not make significant impact to overall gas usage while it makes the code more complex and unsafe.\n##### Recommendation\nIn favour of readability and safety of code. we recommend to avoid unnecessary usage of assembly in Solidity.", + "protocol": "Yearn Finance", + "report_date": "2022-02-28", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/ySwaps/README.md#2-unnecessary-assembly-in-multicalloptimizedswappersol", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/ySwaps/Yearn%20ySwaps%20Security%20Audit%20Report.pdf" + }, + { + "title": "Variables can be declared as immutable", + "content": "##### Description\nFollowing variables of both sync and async Bancor swappers can be declared as immutable: `contractRegistry`, `bancorNetworkName` at https://github.com/yearn/hardhat-monorepo/blob/ecc0b5147992b34c315e08af170ceb4a5fe071ee/packages/yswaps/contracts/swappers/async/BancorSwapper.sol#L40-L41 and `contractRegistry`, `bancorNetworkName` at https://github.com/yearn/hardhat-monorepo/blob/ecc0b5147992b34c315e08af170ceb4a5fe071ee/packages/yswaps/contracts/swappers/sync/BancorSwapper.sol#L38-L39\n##### Recommendation\nWe recommend to declare mentioned variables as immutable.\n\n***\n", + "protocol": "Yearn Finance", + "report_date": "2022-02-28", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/ySwaps/README.md#3-variables-can-be-declared-as-immutable", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/ySwaps/Yearn%20ySwaps%20Security%20Audit%20Report.pdf" + }, + { + "title": "Duplicating sanity check", + "content": "##### Description\nSanity check `maxSlippage != 0` at https://github.com/yearn/hardhat-monorepo/blob/ecc0b5147992b34c315e08af170ceb4a5fe071ee/packages/yswaps/contracts/TradeFactory/TradeFactoryExecutor.sol#L81 duplicates sanity check at https://github.com/yearn/hardhat-monorepo/blob/ecc0b5147992b34c315e08af170ceb4a5fe071ee/packages/yswaps/contracts/swappers/sync/SyncSwapper.sol#L38\n##### Recommendation\nWe recommend to remove redundant check\n", + "protocol": "Yearn Finance", + "report_date": "2022-02-28", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/ySwaps/README.md#4-duplicating-sanity-check", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/ySwaps/Yearn%20ySwaps%20Security%20Audit%20Report.pdf" + }, + { + "title": "Redundant operation on return values", + "content": "##### Description\nHere are performed some redundant operation on return values of `swapExactTokensForTokens()`:\n- https://github.com/yearn/hardhat-monorepo/blob/ecc0b5147992b34c315e08af170ceb4a5fe071ee/packages/yswaps/contracts/swappers/async/UniswapV2Swapper.sol#L52\n- https://github.com/yearn/hardhat-monorepo/blob/ecc0b5147992b34c315e08af170ceb4a5fe071ee/packages/yswaps/contracts/swappers/sync/UniswapV2AnchorSwapper.sol#L74\n\nIt makes no impact on contract security or perfomance and only noted in favour of graceful code.\n##### Recommendation\nWe recommend to remove redundant operations\n\n***\n", + "protocol": "Yearn Finance", + "report_date": "2022-02-28", + "impact": "LOW", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/ySwaps/README.md#5-redundant-operation-on-return-values", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/ySwaps/Yearn%20ySwaps%20Security%20Audit%20Report.pdf" + }, + { + "title": "Possible underflow", + "content": "##### Description\nIf a ledger's stake drammaticaly decreases due to rebalance and after that the ledger receives a huge slash, then underflow can occur: https://github.com/mixbytes/lido-dot-ksm/blob/76a10efa5f223c4c613f26794802b8fb9bb188e1/contracts/Lido.sol#L608\n\n##### Recommendation\nWe recommend distributing slashes across all the ledgers.\n", + "protocol": "Lido", + "report_date": "2022-02-08", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20KSM/README.md#1-possible-underflow", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20KSM/LIDO%20KSM%20Security%20Audit%20Report.pdf" + }, + { + "title": "Possible overflow on cast to uint", + "content": "##### Description\nIf `newStake` is a negative number, then overflow can occur: https://github.com/mixbytes/lido-dot-ksm/blob/76a10efa5f223c4c613f26794802b8fb9bb188e1/contracts/Lido.sol#L730\n\n##### Recommendation\nWe recommend checking overall diff in order to exclude such scenarios.\n", + "protocol": "Lido", + "report_date": "2022-02-08", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20KSM/README.md#2-possible-overflow-on-cast-to-uint", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20KSM/LIDO%20KSM%20Security%20Audit%20Report.pdf" + }, + { + "title": "Public access to all functions", + "content": "##### Description\nIn contract `Controller` all functions have public access which can be exploited:\nhttps://github.com/mixbytes/lido-dot-ksm/blob/76a10efa5f223c4c613f26794802b8fb9bb188e1/contracts/Controller.sol\n\n##### Recommendation\nWe recommend adding access modificators.\n", + "protocol": "Lido", + "report_date": "2022-02-08", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20KSM/README.md#1-public-access-to-all-functions", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20KSM/LIDO%20KSM%20Security%20Audit%20Report.pdf" + }, + { + "title": "Controller can be initialized several times", + "content": "##### Description\nIn contract `Controller` the `initialize` function can be called several times: https://github.com/mixbytes/lido-dot-ksm/blob/76a10efa5f223c4c613f26794802b8fb9bb188e1/contracts/Controller.sol#L140\n\n##### Recommendation\nWe recommend adding the `initializer` modifier.\n", + "protocol": "Lido", + "report_date": "2022-02-08", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20KSM/README.md#2-controller-can-be-initialized-several-times", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20KSM/LIDO%20KSM%20Security%20Audit%20Report.pdf" + }, + { + "title": "Incorrect condition", + "content": "##### Description\nThe condition is incorrect here that can lead to an infinite loop: https://github.com/mixbytes/lido-dot-ksm/blob/76a10efa5f223c4c613f26794802b8fb9bb188e1/contracts/Lido.sol#L748\n\n##### Recommendation\nWe recommend changing `||` into `&&`.\n", + "protocol": "Lido", + "report_date": "2022-02-08", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20KSM/README.md#3-incorrect-condition", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20KSM/LIDO%20KSM%20Security%20Audit%20Report.pdf" + }, + { + "title": "Possible burn of zero shares", + "content": "##### Description\nDue to rounding errors a user can burn zero shares: https://github.com/mixbytes/lido-dot-ksm/blob/76a10efa5f223c4c613f26794802b8fb9bb188e1/contracts/Lido.sol#L522\n\n##### Recommendation\nWe recommend adding a check so that a user couldn't burn zero shares.\n", + "protocol": "Lido", + "report_date": "2022-02-08", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20KSM/README.md#4-possible-burn-of-zero-shares", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20KSM/LIDO%20KSM%20Security%20Audit%20Report.pdf" + }, + { + "title": "Possible division by zero", + "content": "##### Description\nIn some cases division by zero can take place here:\n- https://github.com/mixbytes/lido-dot-ksm/blob/76a10efa5f223c4c613f26794802b8fb9bb188e1/contracts/Lido.sol#L658\n- https://github.com/mixbytes/lido-dot-ksm/blob/76a10efa5f223c4c613f26794802b8fb9bb188e1/contracts/Lido.sol#L708\n\n##### Recommendation\nWe recommend to set a stake to zero if the overall shares amount is equal to zero.\n", + "protocol": "Lido", + "report_date": "2022-02-08", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20KSM/README.md#5-possible-division-by-zero", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20KSM/LIDO%20KSM%20Security%20Audit%20Report.pdf" + }, + { + "title": "Insufficient xcKSm balance on `Lido`", + "content": "##### Description\nIt is possible that `Lido` can have less than `_readyToClaim` : https://github.com/mixbytes/lido-dot-ksm/blob/76a10efa5f223c4c613f26794802b8fb9bb188e1/contracts/Lido.sol#L563\n\n##### Recommendation\nWe recommend to add a requirement that `Lido` would have enough tokens to transfer.\n", + "protocol": "Lido", + "report_date": "2022-02-08", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20KSM/README.md#5-insufficient-xcksm-balance-on-lido", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20KSM/LIDO%20KSM%20Security%20Audit%20Report.pdf" + }, + { + "title": "Possible zero balance on `Lido`", + "content": "##### Description\nIt is possible that `Lido` can have zero balance on reward distribution: https://github.com/mixbytes/lido-dot-ksm/blob/76a10efa5f223c4c613f26794802b8fb9bb188e1/contracts/Lido.sol#L588\n\n##### Recommendation\nWe recommend to add a check for the case when `Lido` has zero balance on reward distribution.\n", + "protocol": "Lido", + "report_date": "2022-02-08", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20KSM/README.md#6-possible-zero-balance-on-lido", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20KSM/LIDO%20KSM%20Security%20Audit%20Report.pdf" + }, + { + "title": "Possible underflow", + "content": "##### Description\nIt is possible that free balance from the report can be less than free balance from the previous era: https://github.com/mixbytes/lido-dot-ksm/blob/76a10efa5f223c4c613f26794802b8fb9bb188e1/contracts/Ledger.sol#L297\n\n##### Recommendation\nWe recommend to add a variable to control which amount should be bonded on the next era.\n", + "protocol": "Lido", + "report_date": "2022-02-08", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20KSM/README.md#7-possible-underflow", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Lido%20KSM/LIDO%20KSM%20Security%20Audit%20Report.pdf" + }, + { + "title": "Possible incorrect `scaledTotalSupply` calculation", + "content": "##### Description\nAt the line\nhttps://github.com/lidofinance/aave-protocol-v2/blob/12c9111990c9699e84a36f30ba849486ef8f2a84/contracts/protocol/tokenization/lido/AStETH.sol#L595\nif the shares are below zero then value may overflow and scaled total supply calculation will be wrong.\n\n##### Recommendation\nBefore converting a negative number to the `uint256` type, you must make it positive.", + "protocol": "Lido", + "report_date": "2022-02-07", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Aave%20stETH/README.md#1-possible-incorrect-scaledtotalsupply-calculation", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Aave%20stETH/Lido%20Aave%20stETH%20Security%20Audit%20Report.pdf" + }, + { + "title": "Token Bridging doesn't work with Wormhole fees", + "content": "##### Description\nLine \n- https://github.com/certusone/wormhole/blob/9bc408ca1912e7000c5c2085215be9d44713028b/ethereum/contracts/bridge/Bridge.sol#L93\nhas a `transferTokens ()` function of type `payable`. In the body of this function, on line 133, a call to the internal \nfunction `logTransfer ()` is made and one of the parameters `msg.value` is passed.\nAt line \n- https://github.com/certusone/wormhole/blob/9bc408ca1912e7000c5c2085215be9d44713028b/ethereum/contracts/bridge/Bridge.sol#L151\nfrom the `logTransfer()` function, the `publishMessage()` function is called.\nThe `publishMessage()` function of type `payable` on the line:\n- https://github.com/certusone/wormhole/blob/9bc408ca1912e7000c5c2085215be9d44713028b/ethereum/contracts/Implementation.sol#L21\nthe condition for payment of the commission must be met.\n```\n require(msg.value == messageFee(), \"invalid fee\");\n```\n\nIn the checked contract, at line \n- https://github.com/lidofinance/anchor-collateral-steth/blob/8d52ce72cb42d48dff1851222e3b624c941ddb30/contracts/BridgeConnectorWormhole.vy#L49\na call to the `transferTokens()` function from the `_transfer_asset()` function is made. \nBut there is no `@payable` modifier anywhere and no `msg.value` value handling.\nTherefore, the `_transfer_asset()` function will not work.\nAs a result, the `submit ()` and `collect_rewards ()` functions will not work in the `AnchorVault.vy` contract, \nbecause there is no commission fee for the `Wormhole` system.\n##### Recommendation\nIt is required to add a commission payment for the `Wormhole` system.", + "protocol": "Lido", + "report_date": "2022-01-25", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Anchor%20Collateral%20stETH/README.md#1-token-bridging-doesnt-work-with-wormhole-fees", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Anchor%20Collateral%20stETH/Lido%20Anchor%20Collateral%20stETH%20Security%20Audit%20Report.pdf" + }, + { + "title": "Incorrect calculation of borrowed amount", + "content": "##### Description\nTotal borrowed amount increases unequally, so total borrowed amount on credit accounts would be less than `totalBorrowed` on a `PoolService` which would lead to incorrect calcultaions for LP of a `PoolService`:\nhttps://github.com/Gearbox-protocol/gearbox-contracts/blob/0ac33ba87212ce056ac6b6357ad74161d417158a/contracts/credit/CreditManager.sol#L661\n##### Recommendation\nWe recommend to change calculation of borrowed amount for credit accounts.", + "protocol": "GearBox Protocol", + "report_date": "2021-12-23", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/GearBox%20Protocol/README.md#1-incorrect-calculation-of-borrowed-amount", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/GearBox%20Protocol/GearBox%20Protocol%20Security%20Audit%20Report.pdf" + }, + { + "title": "Possible remove of necessary adapter", + "content": "##### Description\nIn case 1 adapter is used for several contracts, then next lines will break work of these contracts:\nhttps://github.com/Gearbox-protocol/gearbox-contracts/blob/0ac33ba87212ce056ac6b6357ad74161d417158a/contracts/credit/CreditFilter.sol#L190\nhttps://github.com/Gearbox-protocol/gearbox-contracts/blob/0ac33ba87212ce056ac6b6357ad74161d417158a/contracts/credit/CreditFilter.sol#L217\n##### Recommendation\nWe recommend adding a check, that removed adapter is not used in other contracts.", + "protocol": "GearBox Protocol", + "report_date": "2021-12-23", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/GearBox%20Protocol/README.md#1-possible-remove-of-necessary-adapter", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/GearBox%20Protocol/GearBox%20Protocol%20Security%20Audit%20Report.pdf" + }, + { + "title": "Incorrect change of state", + "content": "##### Description\nChanging state to true is incorrect and must be done via `allowToken()`:\nhttps://github.com/Gearbox-protocol/gearbox-contracts/blob/0ac33ba87212ce056ac6b6357ad74161d417158a/contracts/credit/CreditFilter.sol#L398\n##### Recommendation\nWe recommend allowing changing state only to false.", + "protocol": "GearBox Protocol", + "report_date": "2021-12-23", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/GearBox%20Protocol/README.md#2-incorrect-change-of-state", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/GearBox%20Protocol/GearBox%20Protocol%20Security%20Audit%20Report.pdf" + }, + { + "title": "`creditManager` isn't checked", + "content": "##### Description\nIt is possible to give unlimited approve to poisoned contract:\nhttps://github.com/Gearbox-protocol/gearbox-contracts/blob/0ac33ba87212ce056ac6b6357ad74161d417158a/contracts/credit/LeverageActions.sol#L222\n##### Recommendation\nWe recommend adding a check that `creditManager` is a system contract.", + "protocol": "GearBox Protocol", + "report_date": "2021-12-23", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/GearBox%20Protocol/README.md#3-creditmanager-isnt-checked", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/GearBox%20Protocol/GearBox%20Protocol%20Security%20Audit%20Report.pdf" + }, + { + "title": "Uncounted fees in USDT", + "content": "##### Description\nContract can have less than `amountIn` because of fees in transferFrom function in USDT:\nhttps://github.com/Gearbox-protocol/gearbox-contracts/blob/0ac33ba87212ce056ac6b6357ad74161d417158a/contracts/credit/LeverageActions.sol#L232\nhttps://github.com/Gearbox-protocol/gearbox-contracts/blob/0ac33ba87212ce056ac6b6357ad74161d417158a/contracts/credit/LeverageActions.sol#L324\n##### Recommendation\nWe recommend to call `openCreditAccount` with current contract balance.", + "protocol": "GearBox Protocol", + "report_date": "2021-12-23", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/GearBox%20Protocol/README.md#4-uncounted-fees-in-usdt", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/GearBox%20Protocol/GearBox%20Protocol%20Security%20Audit%20Report.pdf" + }, + { + "title": "Possible loss of assets by mistake", + "content": "##### Description\nIf a liquidator calls this function by mistake with the next parameters: `to = address(0), force = true`, then he loses all assets:\nhttps://github.com/Gearbox-protocol/gearbox-contracts/blob/0ac33ba87212ce056ac6b6357ad74161d417158a/contracts/credit/CreditManager.sol#L302\n##### Recommendation\nWe recommend adding a check that `to != address(0)`.", + "protocol": "GearBox Protocol", + "report_date": "2021-12-23", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/GearBox%20Protocol/README.md#5-possible-loss-of-assets-by-mistake", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/GearBox%20Protocol/GearBox%20Protocol%20Security%20Audit%20Report.pdf" + }, + { + "title": "Broken account must be deleted", + "content": "##### Description\nIn case if some tokens cannot be transferred from the account, then this account must be deleted:\nhttps://github.com/Gearbox-protocol/gearbox-contracts/blob/0ac33ba87212ce056ac6b6357ad74161d417158a/contracts/credit/CreditManager.sol#L451\n##### Recommendation\nWe recommend to delete account in case some transfers are reverted.", + "protocol": "GearBox Protocol", + "report_date": "2021-12-23", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/GearBox%20Protocol/README.md#6-broken-account-must-be-deleted", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/GearBox%20Protocol/GearBox%20Protocol%20Security%20Audit%20Report.pdf" + }, + { + "title": "Possible transfer of bad account", + "content": "##### Description\nUser can have bad account with Hf < 1 but not liquidated yet, and transfer it to another user:\nhttps://github.com/Gearbox-protocol/gearbox-contracts/blob/0ac33ba87212ce056ac6b6357ad74161d417158a/contracts/credit/CreditManager.sol#L954\n##### Recommendation\nWe recommend adding approve mechanic, so that account receiver does not receive account that he doesn't want.", + "protocol": "GearBox Protocol", + "report_date": "2021-12-23", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/GearBox%20Protocol/README.md#7-possible-transfer-of-bad-account", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/GearBox%20Protocol/GearBox%20Protocol%20Security%20Audit%20Report.pdf" + }, + { + "title": "Unnecessary allowance", + "content": "##### Description\nVault's withdraw function burns shares, so allowance is unnecessary:\nhttps://github.com/Gearbox-protocol/gearbox-contracts/blob/0ac33ba87212ce056ac6b6357ad74161d417158a/contracts/adapters/YearnV2.sol#L130\n##### Recommendation\nWe recommend removing providing allowance.", + "protocol": "GearBox Protocol", + "report_date": "2021-12-23", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/GearBox%20Protocol/README.md#8-unnecessary-allowance", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/GearBox%20Protocol/GearBox%20Protocol%20Security%20Audit%20Report.pdf" + }, + { + "title": "Incorrect usage of function returned value", + "content": "##### Description\nVault's withdraw function returns amount of tokens which was transferred, not shares:\nhttps://github.com/Gearbox-protocol/gearbox-contracts/blob/0ac33ba87212ce056ac6b6357ad74161d417158a/contracts/adapters/YearnV2.sol#L145\n##### Recommendation\nWe recommend to change function code.", + "protocol": "GearBox Protocol", + "report_date": "2021-12-23", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/GearBox%20Protocol/README.md#9-incorrect-usage-of-function-returned-value", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/GearBox%20Protocol/GearBox%20Protocol%20Security%20Audit%20Report.pdf" + }, + { + "title": "Incorrect taking out of `tail` account", + "content": "##### Description\nIf `creditAccount == tail` then `tail` is not updated properly and this will break the list of accounts:\nhttps://github.com/Gearbox-protocol/gearbox-contracts/blob/0ac33ba87212ce056ac6b6357ad74161d417158a/contracts/core/AccountFactory.sol#L260\n##### Recommendation\nWe recommend updating `tail` if it was taken out.", + "protocol": "GearBox Protocol", + "report_date": "2021-12-23", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/GearBox%20Protocol/README.md#10-incorrect-taking-out-of-tail-account", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/GearBox%20Protocol/GearBox%20Protocol%20Security%20Audit%20Report.pdf" + }, + { + "title": "Incorrect minting", + "content": "##### Description\nBecause of fees in transferFrom function in USDT, contract would have less than `amount`:\nhttps://github.com/Gearbox-protocol/gearbox-contracts/blob/0ac33ba87212ce056ac6b6357ad74161d417158a/contracts/pool/PoolService.sol#L155\n##### Recommendation\nWe recommend to use balance difference to mint Diesel tokens.", + "protocol": "GearBox Protocol", + "report_date": "2021-12-23", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/GearBox%20Protocol/README.md#11-incorrect-minting", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/GearBox%20Protocol/GearBox%20Protocol%20Security%20Audit%20Report.pdf" + }, + { + "title": "Impossible liquidity removing", + "content": "##### Description\nIn case all funds were borrowed (big part of funds), users can't return their assets (`amountSent > balanceOf(address(this))`:\nhttps://github.com/Gearbox-protocol/gearbox-contracts/blob/0ac33ba87212ce056ac6b6357ad74161d417158a/contracts/pool/PoolService.sol#L182\n##### Recommendation\nWe recommend adding a function for closing some account to return funds to LP.", + "protocol": "GearBox Protocol", + "report_date": "2021-12-23", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/GearBox%20Protocol/README.md#12-impossible-liquidity-removing", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/GearBox%20Protocol/GearBox%20Protocol%20Security%20Audit%20Report.pdf" + }, + { + "title": "Calculation can be incorrect", + "content": "##### Description\n`expectedLiquidity` contains real balance + pseudo balance from borrowers interest:\nhttps://github.com/Gearbox-protocol/gearbox-contracts/blob/0ac33ba87212ce056ac6b6357ad74161d417158a/contracts/pool/PoolService.sol#L396\n##### Recommendation\nWe recommend adding a function for forcing closing some accounts to pay all balance for LP.", + "protocol": "GearBox Protocol", + "report_date": "2021-12-23", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/GearBox%20Protocol/README.md#13-calculation-can-be-incorrect", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/GearBox%20Protocol/GearBox%20Protocol%20Security%20Audit%20Report.pdf" + }, + { + "title": "Impossible liquidation of broken account", + "content": "##### Description\nIn case transfer was reverted, then specific token can't be accounted as collateral, and also liquidator must not pay the fee for this token:\nhttps://github.com/Gearbox-protocol/gearbox-contracts/blob/0ac33ba87212ce056ac6b6357ad74161d417158a/contracts/credit/CreditManager.sol#L593-L594\n##### Recommendation\nWe recommend not to accumulate `tv` and `tvw` in case transfer was reverted.", + "protocol": "GearBox Protocol", + "report_date": "2021-12-23", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/GearBox%20Protocol/README.md#14-impossible-liquidation-of-broken-account", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/GearBox%20Protocol/GearBox%20Protocol%20Security%20Audit%20Report.pdf" + }, + { + "title": "Using tokens with whitelist function", + "content": "##### Description\nAt line: https://github.com/Gearbox-protocol/gearbox-contracts/blob/0ac33ba87212ce056ac6b6357ad74161d417158a/contracts/credit/CreditManager.sol#L584-L593\n\nThe Gearbox protocol is assumed to use some tokens which have whitelist function ( ex. USDC, USDT) like a collateral. If this token will be blocked off-chain the Liquidates credit account function member of the `CreditManager` contract (https://github.com/Gearbox-protocol/gearbox-contracts/blob/0ac33ba87212ce056ac6b6357ad74161d417158a/contracts/credit/CreditManager.sol#L300) will not work correctly because the internal function `_transferAssetsTo()` (https://github.com/Gearbox-protocol/gearbox-contracts/blob/0ac33ba87212ce056ac6b6357ad74161d417158a/contracts/credit/CreditManager.sol#L584-L591) returns incorrect return value `totalValue`.\n\n*Example:*\n\n```solidity\nfunction _transferAssetsTo(\n address creditAccount,\n address to,\n bool force\n ) internal returns (uint256 totalValue, uint256 totalWeightedValue) {\n totalValue = 0;\n totalWeightedValue = 0;\n\n uint256 tokenMask;\n uint256 enabledTokens = creditFilter.enabledTokens(creditAccount);\n\n for (uint256 i = 0; i < creditFilter.allowedTokensCount(); i++) {\n tokenMask = 1 << i;\n if (enabledTokens & tokenMask > 0) {\n (\n address token,\n uint256 amount,\n uint256 tv,\n uint256 tvw\n ) = creditFilter.getCreditAccountTokenById(creditAccount, i);\n if (amount > 1) {\n // The condition is met, but the transfer will not occur\n // for blocked account\n _safeTokenTransfer(\n creditAccount,\n token,\n to,\n amount.sub(1),\n force\n );\n // In this case totalValue will not correct\n totalValue += tv;\n totalWeightedValue += tvw;\n }\n }\n }\n```\n\n##### Recommendation\nUse solution where totalValue will not increase in case of unsuccessful transaction.", + "protocol": "GearBox Protocol", + "report_date": "2021-12-23", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/GearBox%20Protocol/README.md#15-using-tokens-with-whitelist-function", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/GearBox%20Protocol/GearBox%20Protocol%20Security%20Audit%20Report.pdf" + }, + { + "title": "Looping a linked list", + "content": "##### Description\nAt the line: https://github.com/Gearbox-protocol/gearbox-contracts/blob/0ac33ba87212ce056ac6b6357ad74161d417158a/contracts/core/AccountFactory.sol#L40\nthere's a linked list called `_nextCreditAccount`.\nIn this list, the account address refers to the address of the next account. Thus, a chain of addresses linked to each other is formed.\nAt the lines contracts/core/AccountFactory.sol#L248-L263 there's a `takeOut ()` function. It takes the credit account address from anywhere on the list and attaches it to the credit manager.\nAt the lines: https://github.com/Gearbox-protocol/gearbox-contracts/blob/0ac33ba87212ce056ac6b6357ad74161d417158a/contracts/core/AccountFactory.sol#L186-L199\n\nthere's a function `returnCreditAccount ()`. It returns the credit account address in the tail of the `_nextCreditAccount` linked list.\nIn the `takeOut()` function there is no logic for checking and zeroing the link to the next account from the taken account address.\nWhen the taken address is returned to the tail of the list, it will contain the old value of the address. Loop through the list may occur when the function `_countCreditAccountsInStock ()` is used for the line: https://github.com/Gearbox-protocol/gearbox-contracts/blob/0ac33ba87212ce056ac6b6357ad74161d417158a/contracts/core/AccountFactory.sol#L352-L365.\n\n##### Recommendation\nIt is necessary to zero the next item from the linked list after the https://github.com/Gearbox-protocol/gearbox-contracts/blob/0ac33ba87212ce056ac6b6357ad74161d417158a/contracts/core/AccountFactory.sol#L260 line:\n```\n _nextCreditAccount[creditAccount] = address(0);\n```", + "protocol": "GearBox Protocol", + "report_date": "2021-12-23", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/GearBox%20Protocol/README.md#16-looping-a-linked-list", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/GearBox%20Protocol/GearBox%20Protocol%20Security%20Audit%20Report.pdf" + }, + { + "title": "No checking of element properties when returning it to the list", + "content": "##### Description\nAt the lines: https://github.com/Gearbox-protocol/gearbox-contracts/blob/0ac33ba87212ce056ac6b6357ad74161d417158a/contracts/core/AccountFactory.sol#L186-L199\nthere's a function `returnCreditAccount ()`. It returns the credit account address in the tail of the `_nextCreditAccount` linked list.\nFor the line: https://github.com/Gearbox-protocol/gearbox-contracts/blob/0ac33ba87212ce056ac6b6357ad74161d417158a/contracts/core/AccountFactory.sol#L192,\nthe check is made that the value of `since ()` is not equal to `block.number`.\nIf the address has never been registered in an `AccountFactory` it will pass this check too.\nBut this address will not be added to the `creditAccounts` array and the logic of the entire contract will be violated.\n\n##### Recommendation\nIt is necessary to make a code correction at the line contracts/core/AccountFactory.sol#L192:\n```\nICreditAccount(usedAccount).since() != block.number &&\nICreditAccount(usedAccount).since() > 0,\n```", + "protocol": "GearBox Protocol", + "report_date": "2021-12-23", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/GearBox%20Protocol/README.md#17-no-checking-of-element-properties-when-returning-it-to-the-list", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/GearBox%20Protocol/GearBox%20Protocol%20Security%20Audit%20Report.pdf" + }, + { + "title": "Withdraw \"with ratio\" without fee via reentrancy", + "content": "##### Description\nTokens with callback e.g. ERC-777 allow easy reentrancy. \nUsers can exploit reentrancy to withdraw with non-equal proportions without fees when call `withdraw` \nafter the first transfer of [`depositFor`](https://github.com/1inch/fixed-rate-swap/blob/0b5a75e9f56e7d21c290dd28c59dc140dcbcc1d5/contracts/FixedRateSwap.sol#L136) or [`_swap`](https://github.com/1inch/fixed-rate-swap/blob/0b5a75e9f56e7d21c290dd28c59dc140dcbcc1d5/contracts/FixedRateSwap.sol#L321)\n\n##### Recommendation\nWe recommend adding nonReentrant modifier to all external functions.\n", + "protocol": "1inch", + "report_date": "2021-11-29", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Fixed%20Rate%20Swap/README.md#1-withdraw-with-ratio-without-fee-via-reentrancy", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Fixed%20Rate%20Swap/1inch%20Fixed%20Rate%20Swap%20Security%20Audit%20Report.pdf" + }, + { + "title": "Impossible withdraw for smart contract", + "content": "##### Description\nIf any smart contract deposits NFT to StakingRewardsV3 it must have `onERC721Received()` function or `withdraw()` will always revert:\nhttps://github.com/keep3r-network/StakingRewardsV3/tree/13ecc6966ae1a413f62224382bfd4d64b1a22351/contracts/StakingRewardsV3-1.sol#L256\n##### Recommendation\nWe recommend to use `transferFrom()` instead of `safeTransferFrom()`.", + "protocol": "Keep3r.Network", + "report_date": "2021-11-11", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Keep3r.Network/README.md#1-impossible-withdraw-for-smart-contract", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Keep3r.Network/keep3r%20Staking%20Rewards%20Security%20Audit%20Report.pdf" + }, + { + "title": "Incorrect update of `totalLiquidity`", + "content": "##### Description\nIf user calls `deposit()` -> `withdraw()` -> `getReward()` then contract will incorrectly calculate `totalLiquidity` which will lead to incorrect calculations of rewards for users:\nhttps://github.com/keep3r-network/StakingRewardsV3/tree/13ecc6966ae1a413f62224382bfd4d64b1a22351/contracts/StakingRewardsV3-1.sol#L342\n##### Recommendation\nWe recommend to change the logic of `update` modificator, so that`totalLiquidity` would update only if NFT is possessed to this contract.", + "protocol": "Keep3r.Network", + "report_date": "2021-11-11", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Keep3r.Network/README.md#2-incorrect-update-of-totalliquidity", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Keep3r.Network/keep3r%20Staking%20Rewards%20Security%20Audit%20Report.pdf" + }, + { + "title": "Incorrect calculation of `rewardPerLiquidity`", + "content": "##### Description\nIf the first user deposits NFT after some time from `notify()` call, then `(lastTimeRewardApplicable() - lastUpdateTime)` always will be less than `DURATION` which leads to freezing some funds on the contract:\nhttps://github.com/keep3r-network/StakingRewardsV3/tree/13ecc6966ae1a413f62224382bfd4d64b1a22351/contracts/StakingRewardsV3-1.sol#L156\n##### Recommendation\nWe recommend to change the calculation of `rewardPerLiquidity`.", + "protocol": "Keep3r.Network", + "report_date": "2021-11-11", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Keep3r.Network/README.md#1-incorrect-calculation-of-rewardperliquidity", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Keep3r.Network/keep3r%20Staking%20Rewards%20Security%20Audit%20Report.pdf" + }, + { + "title": "Possible ddos attack", + "content": "##### Description\nMalicious user can front run `withdraw()` function to change the current price in pool, so user can lost all his rewards:\nhttps://github.com/keep3r-network/StakingRewardsV3/tree/13ecc6966ae1a413f62224382bfd4d64b1a22351/contracts/StakingRewardsV3-1.sol#L195\n##### Recommendation\nWe recommend to get an average price for this check.", + "protocol": "Keep3r.Network", + "report_date": "2021-11-11", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Keep3r.Network/README.md#2-possible-ddos-attack", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Keep3r.Network/keep3r%20Staking%20Rewards%20Security%20Audit%20Report.pdf" + }, + { + "title": "Improper handling of losses in Yearn DAI vault", + "content": "##### Description\nThe strategy is using another Yearn vault to invest DAI to take profit from it. In some rare conditions, that vault can suffer losses. Such conditions are not properly handled.\n\n1. At the [prepareReturn](https://github.com/therealmonoloco/maker-dai-delegate/blob/97949a51062df956fd0172b7b1c778f66844b634/contracts/Strategy.sol#L303) the strategy is not reporting losses from `DAI yVault` until it is completely unable to conceal. As a result, losses are not fairly distributed between vault users. Some users may suffer unfair penalty on withdraw.\n2. At the [liquidatePosition](https://github.com/therealmonoloco/maker-dai-delegate/blob/97949a51062df956fd0172b7b1c778f66844b634/contracts/Strategy.sol#L407) in some conditions, the strategy can overreport losses while it still has enought assets to complete the liquidation request by rebalancing `DAI` debt/collaterial at the `Maker vault`.\n3. The losses in `DAI yVault` are never fixed, so even newcoming investors will not be able to take a profit until recent losses are compensated. On large losses it can take years to recover.\n##### Recommendation\nIt is recommended to implement manual function to fix losses at `DAI yVault`:\n1. To report losses to the parent vault\n2. To rebalance debt/collaterial at Maker vault to make DAI debt equals to DAI balance available to the strategy\n\nIn some rare conditions, the option to flash-borrow WANT tokens from \"the fixer\" can be required to proceed rebalance during a liquidity shortage.", + "protocol": "Yearn Finance", + "report_date": "2021-10-18", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/Maker%20Dai%20Delegate/README.md#1-improper-handling-of-losses-in-yearn-dai-vault", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/Maker%20Dai%20Delegate/Yearn%20Maker%20Dai%20Delegate%20Security%20Audit%20Report.pdf" + }, + { + "title": "Strategy migration reverts after Maker liquidation", + "content": "##### Description\nUnlikely, but possible situation when `Maker` collateral will be liquidated. In this case all operations with collateral will be reverted because the owner would be changed. After the liquidation you can't migrate to a new strategy because `prepareMigration` will be reverted for the above reasons.\n\nhttps://github.com/therealmonoloco/maker-dai-delegate/blob/97949a51062df956fd0172b7b1c778f66844b634/contracts/Strategy.sol#L450\n\n##### Recommendation\nThe `Maker`'s contract does not provide any functionality for getting the collateral's owner by cdpId (for checking that the liquidation didn't happen). That's why you have to cautch all exceptions of transferCdp call by using try/catch functionality in Solidity (0.6 and higher) and check the security modifier error. \n", + "protocol": "Yearn Finance", + "report_date": "2021-10-18", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/Maker%20Dai%20Delegate/README.md#2-strategy-migration-reverts-after-maker-liquidation", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/Maker%20Dai%20Delegate/Yearn%20Maker%20Dai%20Delegate%20Security%20Audit%20Report.pdf" + }, + { + "title": "Decrease in the amount of tokens during exchange due to arithmetic overflow of a variable", + "content": "##### Description\nAt the lines:\n- https://github.com/1inch/1inch-contract/blob/93868c483180cf74fc2551568f0396938b3eeaa8/contracts/UnoswapV3Router.sol#L166 \u0438 \n- https://github.com/1inch/1inch-contract/blob/93868c483180cf74fc2551568f0396938b3eeaa8/contracts/UnoswapV3Router.sol#L175 \na number with the type `uint256` is converted to a number with the type` int256`. This number is passed in the function parameter and, after conversion, is sent to the `UniswapV3Pool` contract.\nBut, if the value of the number is greater than the maximum value for the type `int256`, an arithmetic overflow will occur.\nThis is demonstrated by the following example: https://gist.github.com/mixbytes-audit/b471cc82105f856d1546ba638de20f4e.\nFor example, if you take the number `57896044618658097711785492504343953926634992332820282019728792003956564819970`, then after the conversion you get the value`-5789604461865809771178549250434395392663499233282028206672879199039`\nWe see a decrease in modulus of the initial value of the variable.\n\n##### Recommendation\nBefore lines 166 and 175, you need to check that the value of the number is less than the maximum value for the type `int256`.\n", + "protocol": "1inch", + "report_date": "2021-10-01", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Aggregation%20Router%20V4/README.md#1-decrease-in-the-amount-of-tokens-during-exchange-due-to-arithmetic-overflow-of-a-variable", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Aggregation%20Router%20V4/1Inch%20Aggregation%20Router%20V4%20Security%20Audit%20Report.pdf" + }, + { + "title": "Increase in the amount of tokens during exchange due to arithmetic overflow of a variable", + "content": "##### Description\nAt the lines:\n- https://github.com/1inch/1inch-contract/blob/93868c483180cf74fc2551568f0396938b3eeaa8/contracts/UnoswapV3Router.sol#L170 \u0438 \n- https://github.com/1inch/1inch-contract/blob/93868c483180cf74fc2551568f0396938b3eeaa8/contracts/UnoswapV3Router.sol#L179 \nthe number with the type `int256` is converted to the number with the type` uint256`. The number is taken with a minus sign.\nBut before that, there is no check that the number is less than 0.\nIf we take a small positive value and apply the transformation `uint256(-amount)` to it, we get a very large value due to arithmetic overflow.\nThis is demonstrated by the following example https://gist.github.com/mixbytes-audit/b471cc82105f856d1546ba638de20f4e.\nFor example, if you take the number `1000`, then after conversion you get the value` 115792089237316195423570985008687907853269984665640564039457584007913129638936`.\nWe see an increase in the initial value of the variable.\n\n##### Recommendation\nBefore lines 166 and 175, you need to check the value of the variable for being less than 0.\nIf the value of the variable is positive, then do not do the conversion.\n", + "protocol": "1inch", + "report_date": "2021-10-01", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Aggregation%20Router%20V4/README.md#2-increase-in-the-amount-of-tokens-during-exchange-due-to-arithmetic-overflow-of-a-variable", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Aggregation%20Router%20V4/1Inch%20Aggregation%20Router%20V4%20Security%20Audit%20Report.pdf" + }, + { + "title": "No validation of the value of the variable `msg.value`", + "content": "##### Description\nAt the lines https://github.com/1inch/1inch-contract/blob/93868c483180cf74fc2551568f0396938b3eeaa8/contracts/ClipperRouter.sol#L57-L68 \nprocessing of the input data is done before the exchange procedure.\n`ETH` is not required to work with `WETH` and regular tokens. But the user can inadvertently transfer it.\nIn this case, the user will lose these `ETH`.\nTo prevent this from happening, you need to add checks before lines 60 and 67:\n```solidity=\n require(msg.value == 0, \"CL1IN: wrong msg.value\");\n```\n\n##### Recommendation\nAdditional checks need to be added.\n", + "protocol": "1inch", + "report_date": "2021-10-01", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Aggregation%20Router%20V4/README.md#3-no-validation-of-the-value-of-the-variable-msgvalue", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Aggregation%20Router%20V4/1Inch%20Aggregation%20Router%20V4%20Security%20Audit%20Report.pdf" + }, + { + "title": "Changing the shared variable can affect previous votes", + "content": "##### Description\nAt the lines \nhttps://github.com/lidofinance/aragon-apps/blob/8c46da8704d0011c42ece2896dbf4aeee069b84a/apps/voting/contracts/Voting.sol#L126-L133 in the `unsafelyChangeVoteTime()` method is a change in the common for all voting variable `voteTime`.\nChanging this variable will extend or shorten the voting time on existing voting.\nThis will affect the voting results, because the process will not go as planned when creating a vote.\nSo this action is potentially dangerous and may bring the unexpected side effects.\n\n##### Recommendation\nIt is recommended to save the value of the variable `voteTime` in the structure `Vote`. \nThis will be done in the same way as for the `supportRequiredPct` and `minAcceptQuorumPct` variables.", + "protocol": "Lido", + "report_date": "2021-10-01", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Aragon%20Voting/README.md#1-changing-the-shared-variable-can-affect-previous-votes", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Lido/Aragon%20Voting/LIDO%20Aragon%20Voting%20Security%20Audit%20Report.pdf" + }, + { + "title": "Transactions frontrunning", + "content": "##### Description\nThe code in this line contains an error in calculation\nin line: https://github.com/1inch/fee-collector/blob/3c2626763fd829500496f15476d5e98fbdf4f574/contracts/FeeCollector.sol#L360\n\n`uint256 returnAmount = amount * tokenBalance / value(erc20);`\n \nAccording to the formula, it is fixed price for the rest of tokenBalance or whole amount, not the price for unit.\n\n*Example:\n\nSomeone(something) makes updateReward for 10 WETH - user1\nLet's assume now we have minimal price after a long period of time\n\nCurrent price is 100 Inch for 10 WETH\nuser2 and user3 are atackers\n\nUser4 wants to make a full trade. He wants to buy 10 WETH for 100 1Inch. He wants make a transaction \n\nattacker puts the next transaction before User4\nUser2 updateReward with ~101010 WETH\nthe price is changed\nUser3 trades after User2 ~101010.mul(price) \nUser2 executes trade\nattacker has a profit equal ~1.4 WETH\n\nUser4 got ~8.6 WETH. 1.4 WETH less that expected*\n\n*Example 2\n\nLet's assume, now we have minimal price after a long period of time\nSomeone(something) makes updateReward for 10 WETH - user1\nCurrent price is 100 Inch for 10 WETH\n\nUser2 and User3 want to make partial trade. They want to buy 5 WETH for 50 1Inch. They make a transaction at approximately the same time\n\n\nUser2 trades first and gets 5 WETH and spends ~50 1Inch. OK\nUser3 trades after User 2.5WETH and spends ~50 Inch. Not correct\n\nUser1 never gets his 1Inch because User3 or nobody wants to make this incorrect transaction\n\nIn case User3 makes transaction for 5 WETH and ~spends 100 1Inch, User1 will receive ~2 times more 1Inch than excpected*\n\n##### Recommendation\nImplement correct returnAmount calculation", + "protocol": "1inch", + "report_date": "2021-09-06", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Fee%20Collector/README.md#1-transactions-frontrunning", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Fee%20Collector/1Inch%20Fee%20Collector%20Security%20Audit%20Report.pdf" + }, + { + "title": "Shorted root hash can be brute forced", + "content": "##### Description\nMalicious user can brute force proof for case `leaf = _keccak128(abi.encodePacked(address(malicious_user), token.balanceOf(address(this))))` because root hash is shorted:\nhttps://github.com/1inch/cumulative-merkle-drop/tree/96fb63d0cbfea73603e7500961c71e8ab1fb8c10/contracts/CumulativeMerkleDrop128.sol#L95\nhttps://github.com/1inch/cumulative-merkle-drop/tree/96fb63d0cbfea73603e7500961c71e8ab1fb8c10/contracts/CumulativeMerkleDrop160.sol#L95\n##### Recommendation\nWe recommend to use only 256bit implementation of cumulative merkle drop, because it is a garauntee that hash collision wouldn't appear.", + "protocol": "1inch", + "report_date": "2021-08-26", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Cumulative%20Merkle%20Drop/README.md#1-shorted-root-hash-can-be-brute-forced", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/1inch/Cumulative%20Merkle%20Drop/1Inch%20Cumulative%20Merkle%20Drop%20Security%20Audit%20Report.pdf" + }, + { + "title": "Invalid variable check", + "content": "##### Description\nThe `_executeTransaction()` function in https://github.com/aave/governance-crosschain-bridges/blob/763ef5da8befff3a129443a3ff4ef7ca4d3bb446/contracts/BridgeExecutorBase.sol#L225 can be called several times from the `execute()` function in https://github.com/aave/governance-crosschain-bridges/blob/763ef5da8befff3a129443a3ff4ef7ca4d3bb446/contracts/BridgeExecutorBase.sol#L58.\nEach time the line https://github.com/aave/governance-crosschain-bridges/blob/763ef5da8befff3a129443a3ff4ef7ca4d3bb446/contracts/BridgeExecutorBase.sol#L248 checks the `value` and `msg.value` variables.\nBut this is not correct, because it is necessary to compare the sum of all values of the array of `values[]` and `msg.value` in the `execute()` function. \n\n##### Recommendation\nIt is recommended to do the correct check of the variable.\n", + "protocol": "AAVE", + "report_date": "2021-08-12", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/AAVE/Governance%20Crosschain%20Bridges%20V2/README.md#1-invalid-variable-check", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/AAVE/Governance%20Crosschain%20Bridges%20V2/Aave%20Governance%20Crosschain%20Bridges%20V2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Balance drain with deposit/withdraw repeat", + "content": "##### Description\nThe `deposit` and the `withdraw` are using different base value for conversion between vault shares into user deposits. The `withdraw` is based on [liquidity amount plus `free tokens`](https://github.com/mellow-finance/mellow-contracts/blob/702dc5a2a8a6dd70a3faf45838934321cacf4b49/contracts/LiquidityVault.sol#L198), however `deposit` is based on [liquidity amount only](https://github.com/mellow-finance/mellow-contracts/blob/702dc5a2a8a6dd70a3faf45838934321cacf4b49/contracts/LiquidityVault.sol#L126). The attacker can drain vault balance by making deposit/withdraw repeatedly. The exploit is provided.\n\n##### Recommendation\nIt is recommended to make accounting of deposit/withdraw operation properly", + "protocol": "Mellow Finance", + "report_date": "2021-07-19", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Mellow%20Finance/README.md#1-balance-drain-with-depositwithdraw-repeat", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Mellow%20Finance/Mellow%20Finance%20SCA.pdf" + }, + { + "title": "Possible withdraw unavailiability", + "content": "##### Description\nThe amount of transferred out tokens are not accounted at the vault state while processing user withdrawals. This will cause attempt to withdraw incorrect (too large) amount and probable almost any withdrawals attempts will be reverted.\n##### Recommendation\nIt is recommended to make accounting of deposit/withdraw operation properly", + "protocol": "Mellow Finance", + "report_date": "2021-07-19", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Mellow%20Finance/README.md#1-possible-withdraw-unavailiability", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Mellow%20Finance/Mellow%20Finance%20SCA.pdf" + }, + { + "title": "Losses are not taken into account in the strategy", + "content": "##### Description\nThe withdrawer from vault should incur the losses from liquidation caused by his own withdrawal. However, the [liquidatePosition()](https://github.com/orbxball/liquity-stability-pool/blob/c3fa76af0a4e2d5fd7132b8e24361d5b7439a75d/contracts/Strategy.sol#L307) is ignoring possible trove liquidation. Currenly liquidation will cause revert, but even if not, currently strategy is ignoring the case of trove liquidation. This may lead to improper accounting of user balances and possible locking of vault withdrawals.\n\n##### Recommendation\nIt is recommended to rewrite logic of `liquidatePosition()` considering the liquidation.\n", + "protocol": "Yearn Finance", + "report_date": "2021-06-02", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/Liquity%20Stability%20Pool/README.md#1-losses-are-not-taken-into-account-in-the-strategy", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/Liquity%20Stability%20Pool/Liquity%20stability%20pool%20Security%20Audit%20Report.pdf" + }, + { + "title": "Malfunction of strategy and entire vault on unexpected trove status", + "content": "##### Description\nA *liquity trove* can be in one of several states: *nonExistent, active, closedByOwner, closedByLiquidation, closedByRedemption*. When the *trove* is in state different than *active*, any call to *ajdustTrove()* will fail. Unfortunately, the strategy does not implement proper handling of trove state. There is some scenarios that will cause trove to be in unexpected state: trove liquidation, full collaterial redemption and trove manual *[closing](https://github.com/orbxball/liquity-stability-pool/blob/c3fa76af0a4e2d5fd7132b8e24361d5b7439a75d/contracts/Strategy.sol#L374)* by priveleged user.\n\nThe [*_deposit()*](https://github.com/orbxball/liquity-stability-pool/blob/c3fa76af0a4e2d5fd7132b8e24361d5b7439a75d/contracts/Strategy.sol#L216) function is expected only two states: *zero* (which is *nonExistent*) and other (which is *active, closedByOwner, closedByLiquidation, closedByRedemption*). However, only *active* state is valid for *[adjustTrove](https://github.com/orbxball/liquity-stability-pool/blob/c3fa76af0a4e2d5fd7132b8e24361d5b7439a75d/contracts/Strategy.sol#L237)*, other three states will cause revert.\n\nThe *[liquidatePosition()](https://github.com/orbxball/liquity-stability-pool/blob/c3fa76af0a4e2d5fd7132b8e24361d5b7439a75d/contracts/Strategy.sol#L307)* function does not handle trove state. When trove is in any state except *active*, *liquidatePosition()* will revert on *[adjustTrove()](https://github.com/orbxball/liquity-stability-pool/blob/c3fa76af0a4e2d5fd7132b8e24361d5b7439a75d/contracts/Strategy.sol#L322)* call. This will break harvest() and withdraw() functions so strategy will become broken and should be manually removed from the vault to prevent blocking of any withdrawal from it.\n\n##### Recommendation\nIt is recommended to handle state of the trove properly.\n", + "protocol": "Yearn Finance", + "report_date": "2021-06-02", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/Liquity%20Stability%20Pool/README.md#2-malfunction-of-strategy-and-entire-vault-on-unexpected-trove-status", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/Liquity%20Stability%20Pool/Liquity%20stability%20pool%20Security%20Audit%20Report.pdf" + }, + { + "title": "\"Sandwich attack\" on user withdrawal", + "content": "##### Description\nIn some rare conditions, the strategy is using AMM DEX to [swap SNX to SUSD](https://github.com/jmonteer/yearnV2-strat-SNX-staking/blob/91b839df4a350d80cb583795bccafe0836fdb732/contracts/Strategy.sol#L348) inside of the user-handled transaction. This is vulnerable to the \"sandwich attack\".\n\n##### Recommendation\nAlthough vulnerability conditions are rare and hard to exploit, it is recommended to protect AMM DEX swap operations with slippage technique.\n", + "protocol": "Yearn Finance", + "report_date": "2021-05-24", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/SNX/README.md#1-sandwich-attack-on-user-withdrawal", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/SNX/SNX%20Security%20Audit%20Report.pdf" + }, + { + "title": "Losses are not taken into account in the strategy", + "content": "##### Description\nAt line: https://github.com/orbxball/weth-maker/blob/39cfbee59bcebfce19a5b9ac6f11fb84f3ab7b23/contracts/Strategy.sol#L260 when strategy calls the `liquidatePosition()` function if at this point yvdai have losses we have three branches:\n\n - if `_amountNeeded` > real balance of strategy after all liquidations we got revert (it's not very good, because users can't withdraw their funds);\n - if `_amountNeeded` < real balance of strategy user will withdraw funds, but vault won't consider losses and all losses will be distributed across all users who left after first withdraw;\n - if `yvdai` have losses more than 0.01([default BPS](https://github.com/yearn/yearn-vaults/blob/v0.3.2/contracts/Vault.vy#L928)) `liquidatePosition()` will reverted while [yvdai.withdraw](https://github.com/orbxball/weth-maker/blob/39cfbee59bcebfce19a5b9ac6f11fb84f3ab7b23/contracts/Strategy.sol#L377) (so that means that if yvdai got losses of more than 0.01% any strategies depending on it will be blocked.\n\n\nFixes commentary:\n* Fixed: \n - Withdrawals from underlying DAI vault with losses can be approved.\n - Withdrawals on failed to liquidate will not be reverted.\n* Problem remains: \n - If the strategy suffer a loss from DAI vault, a bad debt will be formed. This debt is hidden until the vault is trying to liquidate it. So we have a bit unfair distribution of losses between vault users.\n\n##### Recommendation\nIt is recommended to rewrite logic of `liquidatePosition()` considering the losses.\n", + "protocol": "Yearn Finance", + "report_date": "2021-05-07", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/Weth%20Maker/README.md#1-losses-are-not-taken-into-account-in-the-strategy", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/Weth%20Maker/Weth%20Maker%20SCA.pdf" + }, + { + "title": "Losses are not taken into account in the strategy", + "content": "##### Description\nAt line: https://github.com/orbxball/yfi-maker/blob/63af6fcfa536073f00d652f49befd18e429b5500/contracts/Strategy.sol#L264-L277\nthe `liquidatePosition()` function does not take into account the value of the`_loss` variable accounting in `prepareReturn()` function. In this case the `liquidatePosition()` function will always return `_liquidatedAmount = _amountNeeded` excluding losses.\nThis implementation may lead to revert when the Vault call the function `withdraw` function (at line https://github.com/yearn/yearn-vaults/blob/952b767fcd597fac8aa2cf5d023532d150bb9236/contracts/BaseStrategy.sol#L681) by reason of the insufficient balance. \n \nAlso the withdrawer from vault should incur the losses from liquidation caused by his own withdrawal. However, the [liquidatePosition()](https://github.com/orbxball/yfi-maker/blob/63af6fcfa536073f00d652f49befd18e429b5500/contracts/Strategy.sol#L264) is ignoring any losses from underlying DAI vault. This may lead to improper accounting of user balances and possible locking of vault withdrawals. \n \n##### Recommendation\nIt is recommended to rewrite logic of `liquidatePosition()` considering the losses.\n", + "protocol": "Yearn Finance", + "report_date": "2021-05-07", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/Yfi%20Maker/README.md#1-losses-are-not-taken-into-account-in-the-strategy", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/Yfi%20Maker/Yfi%20Maker%20SCA.pdf" + }, + { + "title": "Deposit will be unavailable if lending pool address will be updated by AAVE", + "content": "##### Description\nAt line https://github.com/Grandthrax/yearnV2-generic-lender-strat/blob/55b4d3b03845b7b71b24b50baa30823b3e42ebcf/contracts/GenericLender/GenericAave.sol#L132 the `deposit` function assumes recent approval of token transfer. However, the `safeApprove()` is called once during contract initialization(https://github.com/Grandthrax/yearnV2-generic-lender-strat/blob/55b4d3b03845b7b71b24b50baa30823b3e42ebcf/contracts/GenericLender/GenericAave.sol#L49) and possible changes of lending pool address is not tracked properly. If lending pool address is updated by AAVE, the `deposit()` will be unavailable/reverted until contract replacement.\n\n##### Recommendation\nCall `safeApprove()` on demand before calling `deposit()` on lending pool.\n", + "protocol": "Yearn Finance", + "report_date": "2021-04-23", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/Generic%20Lender%20Aave/README.md#1-deposit-will-be-unavailable-if-lending-pool-address-will-be-updated-by-aave", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/Generic%20Lender%20Aave/GenericAave%20SCA.pdf" + }, + { + "title": "Anyone can perform any arbitrary calls on behalf of `VoterProxy`", + "content": "##### Description\nFunction `deposit` in `VoterProxy` defined at https://github.com/convex-eth/platform/blob/754d9e700693246275b613e895b4044b63ce9ed5/contracts/contracts/VoterProxy.sol#L60 accepts call from anyone with any `_token` and `_gauge`, so anyone can craft calldata and make call on behalf of `VoterProxy`. That could lead to undesired behavior, e.g user's funds locked in contract or authorization violation. Also deposit can be called for `_gauge` and `_token` which are not compatible.\nMoreover for now anyone can allow spending tokens from contract balance for any third-party account by calling deposit for target token with evil gauge.\n\n##### Recommendation\nWe strictly recommend to whitelist `_gauge` and `_token`. And also check that `_token` and `_gauge` are compatible(check that ```ICurveGauge(_gauge).withdraw(_amount)``` returns right `_token`)\n", + "protocol": "Convex Platform", + "report_date": "2021-04-19", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Convex%20Platform/README.md#1-anyone-can-perform-any-arbitrary-calls-on-behalf-of-voterproxy", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Convex%20Platform/Convex%20Platform%20Security%20Audit%20Report.pdf" + }, + { + "title": "Unstable gauge version check", + "content": "##### Description\n`ShashFactory` contract have gauge version check based on call probes defined at https://github.com/convex-eth/platform/blob/754d9e700693246275b613e895b4044b63ce9ed5/contracts/contracts/StashFactory.sol#L51-L61, that approach is very dangerous in case of new version added to curve. E.g if curve will add new version of gauge that have `rewarded_token()` or `reward_tokens(uint256)` and with different behavior, then version checker will wrongly classify version and allow to create stash with invalid version. That can lead to broken logic.\n\n##### Recommendation\nWe recommend to use another approach to check version, e.g whitelisting gauges. Curve have only around ~40 gauges.\n", + "protocol": "Convex Platform", + "report_date": "2021-04-19", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Convex%20Platform/README.md#1-unstable-gauge-version-check", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Convex%20Platform/Convex%20Platform%20Security%20Audit%20Report.pdf" + }, + { + "title": "Wrong logic in `withdrawAll`", + "content": "##### Description\nAt the moment `withdrawAll` counts balance as: `balanceOfPool(_gauge)` (https://github.com/convex-eth/platform/blob/754d9e700693246275b613e895b4044b63ce9ed5/contracts/contracts/VoterProxy.sol#L92)\n\nCorrect logic should be: `balanceOfPool(_gauge).add(IERC20(_token).balanceOf(address(this)))`.\n\nThe `withdrawAll` method is used by `shutdownSystem` so potentially some tokens could remain in the contract.\n\n##### Recommendation\nIt is recommended to count amount of tokens as `balanceOfPool(_gauge).add(IERC20(_token).balanceOf(address(this)))`.\n", + "protocol": "Convex Platform", + "report_date": "2021-04-19", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Convex%20Platform/README.md#2-wrong-logic-in-withdrawall", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Convex%20Platform/Convex%20Platform%20Security%20Audit%20Report.pdf" + }, + { + "title": "Zero gauge could be added via `addPool`", + "content": "##### Description\nIn `addPool` defined at https://github.com/convex-eth/platform/blob/754d9e700693246275b613e895b4044b63ce9ed5/contracts/contracts/Booster.sol#L160 there is no check for `_gauge` variable. For example during this call\n```soldity\nbooster.addPool(threeCrvSwap, \"0x0000000000000000000000000000000000000000\", 0)\n```\n\nGauge will be found because `get_gauges` returns array like `[address1, address2, 0x0, 0x0, ...]`. Intruder can call some errors in `Booster` logic.\n\nIt's major because at the moment `StashFactory` call `address(0x0).call.value(0)(data)` (https://github.com/convex-eth/platform/blob/754d9e700693246275b613e895b4044b63ce9ed5/contracts/contracts/StashFactory.sol#L53) and due to specific of EVM there is `true`.\n\n##### Recommendation\nWe recommend to add some checks for `_gauge` variable.\n", + "protocol": "Convex Platform", + "report_date": "2021-04-19", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Convex%20Platform/README.md#3-zero-gauge-could-be-added-via-addpool", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Convex%20Platform/Convex%20Platform%20Security%20Audit%20Report.pdf" + }, + { + "title": "Incorrect use of a library function", + "content": "##### Description\nAt the lines \n- https://github.com/yearn/yearn-vaults/tree/e390c2a6b2ba6e2ecc8f3a72a1ea4adfabd17544/contracts/BaseWrapper.sol#L117\n- https://github.com/yearn/yearn-vaults/tree/e390c2a6b2ba6e2ecc8f3a72a1ea4adfabd17544/contracts/BaseWrapper.sol#L198\nuse the `safeApprove()` function from the `SafeERC20` library.\nBut before giving permission for a certain amount of tokens, you first need to zero this value.\nNow the `safeApprove()` function is called only once with a specific value.\nAfter the first call, everything will work, but after the second call, the function will be blocked. \n\n##### Recommendation\nIt is necessary to make a correct call to the `safeApprove()` function:\n```\n token.safeApprove(addressValue, 0);\n token.safeApprove(addressValue, amount);\n``` \n", + "protocol": "Yearn Finance", + "report_date": "2021-04-09", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/Yearn%20Vaults%20V3/README.md#1-incorrect-use-of-a-library-function", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/Yearn%20Vaults%20V3/Yearn%20Vaults%20v.3%20Security%20Audit%20Report.pdf" + }, + { + "title": "Outdated `_cachedVaults` after `registry` changing", + "content": "##### Description\nEach `registry` has own `vaults` variable. It is possible that new `registry` contains different set of Vaults. In `allVaults` function we always copy old `_cachedVaults` https://github.com/yearn/yearn-vaults/blob/e390c2a6b2ba6e2ecc8f3a72a1ea4adfabd17544/contracts/BaseWrapper.sol#L71-73. \n\nThe cache is updated with `allVaults` produce https://github.com/yearn/yearn-vaults/blob/e390c2a6b2ba6e2ecc8f3a72a1ea4adfabd17544/contracts/BaseWrapper.sol#L148-149.\n\nSo we will never update `_cachedVaults` prefix part.\n\n##### Recommendation\nIt is recommended to update all elements of the `_cachedVaults` array in the `setRegistry()` function.\n", + "protocol": "Yearn Finance", + "report_date": "2021-04-09", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/Yearn%20Vaults%20V3/README.md#2-outdated-_cachedvaults-after-registry-changing", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/Yearn%20Vaults%20V3/Yearn%20Vaults%20v.3%20Security%20Audit%20Report.pdf" + }, + { + "title": "Correct migration", + "content": "##### Description\nIn constructor, rights are granted to spend tokens, which should be canceled when migrating the strategy.\n- https://github.com/andy8052/yveCRV-vault/blob/6706b9ad45e71ee9014454419f229adfa6409f1d/contracts/Strategy.sol#L171\n\n##### Recommendation\nIt is recommended to add in function `prepareMigration()`:\n```solidity\n IERC20(crv).safeApprove(address(want), 0);\n IERC20(usdc).safeApprove(sushiswap, 0);\n \n IyveCRV(address(want)).claim();\n want.safeTransfer(_newStrategy, want.balanceOf(address(this)));\n \n IERC20(usdc).safeTransfer(_newStrategy, IERC20(usdc).balanceOf(address(this)));\n \n want.safeApprove(vault, 0);\n vault.approve(rewards, 0);\n```", + "protocol": "Yearn Finance", + "report_date": "2021-04-06", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/yveCRV/README.md#1-correct-migration", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/yveCRV/yveCRV-vault%20Security%20Audit%20Report%20(merged).pdf" + }, + { + "title": "Reward sniffing", + "content": "##### Description\nUser can deposit-withdraw tokens several times (at the same transaction), causing reward sniffing.\nThe emulation of this behavior is presented below:\n```python\ndef main():\n deployer = accounts[0]\n workerOwner = accounts[1]\n \n escrow = deployer.deploy(StakingEscrowMock)\n escrow.setAllTokens(9000)\n\n token = deployer.deploy(EasyToken, 1000_000)\n stacking = deployer.deploy(PoolingStakingContractV2)\n workerFraction = 1\n stacking.initialize(workerFraction, token, escrow, workerOwner, {'from': deployer})\n stacking.enableDeposit({'from': deployer})\n\n user1 = accounts[2]\n user2 = accounts[3]\n deployer.transfer(stacking, 6000)\n token.mint(user1, 1000_000)\n token.mint(user2, 1000_000)\n\n token.approve(stacking, 100_000, {'from': user1})\n stacking.depositTokens(100_000, {'from': user1})\n \n for _ in range(100):\n token.approve(stacking, 100, {'from': user2})\n stacking.depositTokens(100, {'from': user2})\n stacking.withdrawAll({'from': user2})\n \n user1_balance = token.balanceOf(user1)\n user2_balance = token.balanceOf(user2)\n stacking_balance = token.balanceOf(stacking)\n\n print(\"user1_balance\", user1_balance)\n print(\"user2_balance\", user2_balance)\n print(\"stacking_balance\", stacking_balance)\n\n stacking.withdrawAll({'from': user1}) # >>>> ERROR HERE <<<<\n```\n##### Recommendation\nMay be add a check in withdrawAll function to requre deposit DISABLED?\n", + "protocol": "NuCypher", + "report_date": "2021-03-25", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/NuCypher/README.md#1-reward-sniffing", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/NuCypher/NuCypher%20PoolingStakingContractV2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Reentry in `withdrawAll`", + "content": "##### Description\nMalicious token/workerOwner may have a reentry callback to the contract here\n\nhttps://github.com/nucypher/nucypher/blob/main/nucypher/blockchain/eth/sol/source/contracts/staking_contracts/PoolingStakingContractV2.sol#L236\n\nbut the state of the contract changes here\n\nhttps://github.com/nucypher/nucypher/blob/main/nucypher/blockchain/eth/sol/source/contracts/staking_contracts/PoolingStakingContractV2.sol#L247\nit allows to use reentry.\n\n##### Recommendation\nPut transfers as the last statements of the method.\n", + "protocol": "NuCypher", + "report_date": "2021-03-25", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/NuCypher/README.md#1-reentry-in-withdrawall", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/NuCypher/NuCypher%20PoolingStakingContractV2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Withdrawal from an account exceeding availible assets", + "content": "##### Description\nThe contractor discovered a code that is potentially susceptible to contract failure due to throw from another contract.\n- https://github.com/orbxball/stablecoins-3pool/blob/adeb776933c6cb3b8306239cc3357d4c6239a88d/contracts/StrategyDAI.sol#L164\n- https://github.com/orbxball/stablecoins-3pool/blob/adeb776933c6cb3b8306239cc3357d4c6239a88d/contracts/StrategyUSDC.sol#L164\n\n##### Recommendation\nIt is recommended to add validation which was done in the contract:\n- https://github.com/orbxball/stablecoins-3pool/blob/adeb776933c6cb3b8306239cc3357d4c6239a88d/contracts/StrategyUSDT.sol#L163\n", + "protocol": "Yearn Finance", + "report_date": "2021-03-24", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/Stablecoins%203pool/README.md#1-withdrawal-from-an-account-exceeding-availible-assets", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/Stablecoins%203pool/Yearn-stablecoins-3pool%20Security%20Audit%20Report%20(merged).pdf" + }, + { + "title": "Incorrect transfer of parameter values", + "content": "##### Description\nAt the lines:\n- https://github.com/orbxball/stablecoins-3pool/blob/adeb776933c6cb3b8306239cc3357d4c6239a88d/contracts/StrategyUSDC.sol#L222\n- https://github.com/orbxball/stablecoins-3pool/blob/adeb776933c6cb3b8306239cc3357d4c6239a88d/contracts/StrategyUSDT.sol#L224\nthe parameters are not passed correctly.\n\n\n##### Recommendation\nIt is recommended to fixed it.\n", + "protocol": "Yearn Finance", + "report_date": "2021-03-24", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/Stablecoins%203pool/README.md#2-incorrect-transfer-of-parameter-values", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/Stablecoins%203pool/Yearn-stablecoins-3pool%20Security%20Audit%20Report%20(merged).pdf" + }, + { + "title": "Use msgSender instead of msg.sender in Event param", + "content": "##### Description\nSince the contract uses metatransactions everywhere (and uses NativeMetaTransaction), you should always use `msgSender()`\n- https://github.com/RealityCards/RealityCards-Contracts/blob/fd3b713d1a15f92ebc329f85038b76563f1587b8/contracts/RCMarket.sol#L584\n\notherwise the event parameter maybe not correct\n\nlook at the logic at https://github.com/RealityCards/RealityCards-Contracts/blob/fd3b713d1a15f92ebc329f85038b76563f1587b8/contracts/lib/NativeMetaTransaction.sol#L105\n\nBut at https://github.com/RealityCards/RealityCards-Contracts/blob/fd3b713d1a15f92ebc329f85038b76563f1587b8/contracts/RCMarket.sol#L579 the `msgSender()`, so it is used what is not consistent.\n\n##### Recommendation\nIt is recommended to use `msgSender()` in all of `msg.sender` usages (see also: https://medium.com/biconomy/biconomy-supports-native-meta-transactions-243ce52a2a2b).\n", + "protocol": "Reality Cards", + "report_date": "2021-03-23", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Reality%20Cards/README.md#1-use-msgsender-instead-of-msgsender-in-event-param", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Reality%20Cards/RealityCards%20Security%20Audit%20Report.pdf" + }, + { + "title": "No check `_amt` value under withdraw", + "content": "##### Description\nAt the lines:\n- https://github.com/orbxball/stablecoins-ypool/blob/5d80af7aeeff9f9b8f6d47d0334d36db3e97e5e4/contracts/StrategyDAIypool.sol#L207\n- https://github.com/orbxball/stablecoins-ypool/blob/5d80af7aeeff9f9b8f6d47d0334d36db3e97e5e4/contracts/StrategyTUSDypool.sol#L207\n- https://github.com/orbxball/stablecoins-ypool/blob/5d80af7aeeff9f9b8f6d47d0334d36db3e97e5e4/contracts/StrategyUSDCypool.sol#L207\n- https://github.com/orbxball/stablecoins-ypool/blob/5d80af7aeeff9f9b8f6d47d0334d36db3e97e5e4/contracts/StrategyUSDTypool.sol#L207\nthere are not valid available balance on the contract. This will lead to the fact that the `_WithDRAWSome()` function will not always work. \n\nAt the lines:\n- https://github.com/orbxball/stablecoins-ypool/blob/5d80af7aeeff9f9b8f6d47d0334d36db3e97e5e4/contracts/StrategyDAIypool.sol#L265\n- https://github.com/orbxball/stablecoins-ypool/blob/5d80af7aeeff9f9b8f6d47d0334d36db3e97e5e4/contracts/StrategyTUSDypool.sol#L265\n- https://github.com/orbxball/stablecoins-ypool/blob/5d80af7aeeff9f9b8f6d47d0334d36db3e97e5e4/contracts/StrategyUSDCypool.sol#L265\n- https://github.com/orbxball/stablecoins-ypool/blob/5d80af7aeeff9f9b8f6d47d0334d36db3e97e5e4/contracts/StrategyUSDTypool.sol#L265\nthe same in the `forceW()` function.\n\n##### Recommendation\nIt is recommended to add additional check `_amt` value under withdraw operation:\n```soldity\nif (_amt > _before){ \n _amt = _before;\n}\n```\n", + "protocol": "Yearn Finance", + "report_date": "2021-03-22", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/Stablecoins%20Ypool/README.md#1-no-check-_amt-value-under-withdraw", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/Stablecoins%20Ypool/Yearn-stablecoins-ypool%20Security%20Audit%20Report.pdf" + }, + { + "title": "Potential `safeApprove` blocking", + "content": "##### Description\nAt several places, e.g. https://github.com/bondappetit/bondappetit-protocol/blob/355180f0aca0b29d60d808f761052956b7a3a159/contracts/Investment.sol#L182 contract perform `safeApprove` before uniswap's function call, however in case if uniswap doesn't use full provided allowance that can lead to blocking next `safeApprove` call because `safeApprove` requires zero allowance.\n\nAnother lines with same issue:\n- https://github.com/bondappetit/bondappetit-protocol/blob/355180f0aca0b29d60d808f761052956b7a3a159/contracts/Market.sol#L248\n- https://github.com/bondappetit/bondappetit-protocol/blob/355180f0aca0b29d60d808f761052956b7a3a159/contracts/profit/Buyback.sol#L125\n- https://github.com/bondappetit/bondappetit-protocol/blob/355180f0aca0b29d60d808f761052956b7a3a159/contracts/profit/ProfitSplitter.sol#L195\n- https://github.com/bondappetit/bondappetit-protocol/blob/355180f0aca0b29d60d808f761052956b7a3a159/contracts/profit/ProfitSplitter.sol#L204\n- https://github.com/bondappetit/bondappetit-protocol/blob/355180f0aca0b29d60d808f761052956b7a3a159/contracts/profit/UniswapMarketMaker.sol#L116\n- https://github.com/bondappetit/bondappetit-protocol/blob/355180f0aca0b29d60d808f761052956b7a3a159/contracts/profit/UniswapMarketMaker.sol#L124\n- https://github.com/bondappetit/bondappetit-protocol/blob/355180f0aca0b29d60d808f761052956b7a3a159/contracts/profit/UniswapMarketMaker.sol#L125\n- https://github.com/bondappetit/bondappetit-protocol/blob/355180f0aca0b29d60d808f761052956b7a3a159/contracts/profit/UniswapMarketMaker.sol#L151\n- https://github.com/bondappetit/bondappetit-protocol/blob/355180f0aca0b29d60d808f761052956b7a3a159/contracts/profit/UniswapMarketMaker.sol#L152\n- https://github.com/bondappetit/bondappetit-protocol/blob/355180f0aca0b29d60d808f761052956b7a3a159/contracts/profit/UniswapMarketMaker.sol#L181\n\n##### Recommendation\nWe recommend to always reset allowance to zero by calling `safeApprove` with `0` amount.\n", + "protocol": "Bond Appetit", + "report_date": "2021-03-18", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Bond%20Appetit/README.md#1-potential-safeapprove-blocking", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Bond%20Appetit/BondAppetit%20Security%20Audit%20Report.pdf" + }, + { + "title": "Wrongly calculated ETH amount to transfer", + "content": "##### Description\nAt lines https://github.com/bondappetit/bondappetit-protocol/blob/355180f0aca0b29d60d808f761052956b7a3a159/contracts/profit/ProfitSplitter.sol#L198-L205 contract swaps whole `splitterIncomingBalance` to ETH if `splitterIncomingBalance` insufficient to cover gap between `splitterEthBalance` and `amount`, in other words contract try to get as much as closer to `amount` ETH amount. However as we can see in this block of code contract assigns `amountsOut[1]` to `amount`, it's wrong because we need to assign `splitterEthBalance.add(amountsOut[1])`\n\n##### Recommendation\nWe recommend to assign `splitterEthBalance.add(amountsOut[1])` to `amount` instead of `amountsOut[1]`\n", + "protocol": "Bond Appetit", + "report_date": "2021-03-18", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Bond%20Appetit/README.md#2-wrongly-calculated-eth-amount-to-transfer", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Bond%20Appetit/BondAppetit%20Security%20Audit%20Report.pdf" + }, + { + "title": "Potential re-entrancy problem", + "content": "##### Description\nAt the line https://github.com/bondappetit/bondappetit-protocol/blob/355180f0aca0b29d60d808f761052956b7a3a159/contracts/profit/ProfitSplitter.sol#L227 contract transfers incoming tokens to `recipient`, however that place can be re-entered in case of callbacks from `incoming` contract.\n\n##### Recommendation\nWe recommend to add re-entrancy guard\n", + "protocol": "Bond Appetit", + "report_date": "2021-03-18", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Bond%20Appetit/README.md#3-potential-re-entrancy-problem", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Bond%20Appetit/BondAppetit%20Security%20Audit%20Report.pdf" + }, + { + "title": "Blocked LP tokens on contract", + "content": "##### Description\nAt the line https://github.com/bondappetit/bondappetit-protocol/blob/355180f0aca0b29d60d808f761052956b7a3a159/contracts/profit/UniswapMarketMaker.sol#L85 contract changes `incoming` token to another one, while transferring contract sends all remaining `incoming` tokens to `_recipient`, but contract never check remaining incoming <> support LP tokens on contract side. That tokens cannot be rescued anymore after changing incoming.\n\n##### Recommendation\nWe recommend to remove all liquidity before changing `incoming` token\n", + "protocol": "Bond Appetit", + "report_date": "2021-03-18", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Bond%20Appetit/README.md#4-blocked-lp-tokens-on-contract", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Bond%20Appetit/BondAppetit%20Security%20Audit%20Report.pdf" + }, + { + "title": "Missed depositary check", + "content": "##### Description\nIn function `buy` defined at https://github.com/bondappetit/bondappetit-protocol/blob/88680691fe8d872c5fc26e9500d19cf7caaa9861/contracts/CollateralMarket.sol#L120 contract exchanges collateral tokens to stable tokens. But in case of wrong `depositary` that code will lead to collateralization disbalance, that is bad even you have manual `depositary` changing mechanism because `issuer` requires exact list of depositaries and transaction wont fail because `rebalance` call is fault tolerance.\n\n##### Recommendation\nWe recommend check depositary\n", + "protocol": "Bond Appetit", + "report_date": "2021-03-18", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Bond%20Appetit/README.md#5-missed-depositary-check", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Bond%20Appetit/BondAppetit%20Security%20Audit%20Report.pdf" + }, + { + "title": "Invalid depositary add/remove logic", + "content": "##### Description\nAt lines https://github.com/bondappetit/bondappetit-protocol/blob/88680691fe8d872c5fc26e9500d19cf7caaa9861/contracts/depositary/AgregateDepositaryBalanceView.sol#L49, https://github.com/bondappetit/bondappetit-protocol/blob/88680691fe8d872c5fc26e9500d19cf7caaa9861/contracts/depositary/AgregateDepositaryBalanceView.sol#L62 are defined functions to add or remove depositaries, `depositariesIndex` map contains depositary indexes added to `depositaries` array. At line https://github.com/bondappetit/bondappetit-protocol/blob/88680691fe8d872c5fc26e9500d19cf7caaa9861/contracts/depositary/AgregateDepositaryBalanceView.sol#L50 contract requires that `depositariesIndex[depositary] == 0`, that check allow to add already added depositary that have `0` index. Same error at line https://github.com/bondappetit/bondappetit-protocol/blob/88680691fe8d872c5fc26e9500d19cf7caaa9861/contracts/depositary/AgregateDepositaryBalanceView.sol#L64 that don't allow to remove depositary that have index `0`\n\n##### Recommendation\nWe recommend to remaster depositary existing check \n", + "protocol": "Bond Appetit", + "report_date": "2021-03-18", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Bond%20Appetit/README.md#6-invalid-depositary-addremove-logic", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Bond%20Appetit/BondAppetit%20Security%20Audit%20Report.pdf" + }, + { + "title": "Wrongly used `safeApprove`", + "content": "##### Description\nAt line https://github.com/bondappetit/bondappetit-protocol/blob/88680691fe8d872c5fc26e9500d19cf7caaa9861/contracts/Treasury.sol#L51 contract call `safeApprove` method, however that method fails if account have remaining allowed tokens.\n\n##### Recommendation\nWe suggest to reset approval calling\n```soldity\nERC20(token).safeApprove(recipient, 0);\n```\nbefore setting new approval\n", + "protocol": "Bond Appetit", + "report_date": "2021-03-18", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Bond%20Appetit/README.md#7-wrongly-used-safeapprove", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Bond%20Appetit/BondAppetit%20Security%20Audit%20Report.pdf" + }, + { + "title": "Budget payment blocking", + "content": "##### Description\nIn `pay` function of `Budget.sol` contract defined at https://github.com/bondappetit/bondappetit-protocol/blob/355180f0aca0b29d60d808f761052956b7a3a159/contracts/Budget.sol#L109 contract sends ETH to recipients in loop using `transfer` method. As we know `transfer` method limited by 2300 gas, so any single recipient with payable fallback method can block whole `pay` function execution\n\n##### Recommendation\nWe recommend to rework payment scheme to claimable model.\n", + "protocol": "Bond Appetit", + "report_date": "2021-03-18", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Bond%20Appetit/README.md#8-budget-payment-blocking", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Bond%20Appetit/BondAppetit%20Security%20Audit%20Report.pdf" + }, + { + "title": "Excess reserve amount", + "content": "##### Description\nAt lines https://github.com/CreamFi/compound-protocol/blob/e414160eb8a774140457c885bb099baae528df04/contracts/CCapableErc20.sol#L250-L252 contract increases `internalCash` and `totalReserves` values, but it's so strange that `internalCash` increased by `totalFee` and `totalReserves` increased by `reservesFee` so we totally increased assets amount by `reservesFee + totalFee` however user paid only `totalFee`. It seems there are some uncollateralized `reservesFee`. May be there `totalFee` paid by user should be splitted to `internalCash` and `totalReserves` ?\n\n##### Recommendation\nWe recommend to double check that place \n", + "protocol": "C.R.E.A.M. Finance", + "report_date": "2021-03-12", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/C.R.E.A.M.%20Finance/Flashloan/README.md#1-excess-reserve-amount", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/C.R.E.A.M.%20Finance/Flashloan/C.R.E.A.M.%20finance%20flashloan%20Security%20Review%20Report.pdf" + }, + { + "title": "Error while calculating the value", + "content": "##### Description\nThe `getPricePerFullShare()` function for a yDAI token contract returns the value multiplied by a factor of 1e18.\nBut it doesn't divided by 1e18:\n- https://github.com/CoverProtocol/cover-flashloan/tree/bea8cd444aa1791a97b2a81078dc887a835f7949/contracts/CoverFlashBorrower.sol#L90\n- https://github.com/CoverProtocol/cover-flashloan/tree/bea8cd444aa1791a97b2a81078dc887a835f7949/contracts/CoverFlashBorrower.sol#L155\n- https://github.com/CoverProtocol/cover-flashloan/tree/bea8cd444aa1791a97b2a81078dc887a835f7949/contracts/CoverFlashBorrower.sol#L182\n \n##### Recommendation\nIt is recommended to fix the error.\n", + "protocol": "Cover Protocol", + "report_date": "2021-03-10", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Cover%20Protocol/Cover%20Flashloan/README.md#1-error-while-calculating-the-value", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Cover%20Protocol/Cover%20Flashloan/CoverProtocol_cover-flashloan%20Security%20Audit%20Report%20(merged).pdf" + }, + { + "title": "Wrongly used `safeApprove`", + "content": "##### Description\nAt the line https://github.com/CoverProtocol/cover-flashloan/blob/9cb6561f3d40f870252088d3c16c1eed24a93166/contracts/CoverFlashBorrower.sol#L351 contract call `safeApprove` method, however that method fails if account have remaining allowed tokens.\n\n##### Recommendation\nWe suggest to reset approval calling\n```soldity\nERC20(token).safeApprove(recipient, 0);\n```\nbefore setting new approval\n", + "protocol": "Cover Protocol", + "report_date": "2021-03-10", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Cover%20Protocol/Cover%20Flashloan/README.md#2-wrongly-used-safeapprove", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Cover%20Protocol/Cover%20Flashloan/CoverProtocol_cover-flashloan%20Security%20Audit%20Report%20(merged).pdf" + }, + { + "title": "Wrongly increased `participants` amount", + "content": "##### Description\nAt line https://github.com/tosdis/TosDisFinance/blob/be50dbf8a52a8f919694498bf30394d328d88fbb/StakeMaster/contracts/StakingPool.sol#L120 contract increases participants amount, that happens if `user.amount` is zero, however if user will provide zero `_amountToStake` `participants` also will increased. So somebody can increase `participants` infinitely by calling `stakeTokens` with zero stake.\n\n##### Recommendation\nWe recommend increase `participants` only if `_amountToStake` not zero\n", + "protocol": "TosDis", + "report_date": "2021-03-01", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/TosDis/README.md#1-wrongly-increased-participants-amount", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/TosDis/TosDis%20Smart%20Contract%20Audit.pdf" + }, + { + "title": "Potentially differentiating message senders", + "content": "##### Description\nThis warning is about inconsistent message sender address source (`msg.sender` and `_msgSender()`) usage in here: https://github.com/tosdis/TosDisFinance/tree/be50dbf8a52a8f919694498bf30394d328d88fbb/StakeMaster/contracts/FeeToken.sol#L37, https://github.com/tosdis/TosDisFinance/tree/be50dbf8a52a8f919694498bf30394d328d88fbb/StakeMaster/contracts/FeeToken.sol#L39, https://github.com/tosdis/TosDisFinance/tree/be50dbf8a52a8f919694498bf30394d328d88fbb/StakeMaster/contracts/FeeToken.sol#L40.\n\nThis can lead to the incorrect message sender address choice in case, for example, particular function call was a relayed call or meta-transaction-related call.\n\n##### Recommendation\nIt is recommended to switch to some particular message sender address retrieval method to avoid double-ownership (or misownership). In particular, using `AccessContolList` is better to choose `_mseSender()`.\n", + "protocol": "TosDis", + "report_date": "2021-03-01", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/TosDis/README.md#2-potentially-differentiating-message-senders", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/TosDis/TosDis%20Smart%20Contract%20Audit.pdf" + }, + { + "title": "Incorrect check of `timeWindow`", + "content": "##### Description\nAt the line https://github.com/CoverProtocol/cover-core-v2/blob/513f5e502a8e8a623729c2c3480fca4e80fdef39/contracts/ClaimConfig.sol#L50 there is incorrect check of `_newTimeWindow`\n\n##### Recommendation\nChange to `require(_newTimeWindow >= 3 days, \"CC: window too short\");`\n", + "protocol": "Cover Protocol", + "report_date": "2021-02-25", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Cover%20Protocol/Cover%20Protocol%20V2/README.md#1-incorrect-check-of-timewindow", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Cover%20Protocol/Cover%20Protocol%20V2/Cover%20Protocol%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Lack of claim validation", + "content": "##### Description\nAt lines:\n- https://github.com/CoverProtocol/cover-core-v2/blob/513f5e502a8e8a623729c2c3480fca4e80fdef39/contracts/ClaimManagement.sol#L112\n- https://github.com/CoverProtocol/cover-core-v2/blob/513f5e502a8e8a623729c2c3480fca4e80fdef39/contracts/ClaimManagement.sol#L145\n- https://github.com/CoverProtocol/cover-core-v2/blob/513f5e502a8e8a623729c2c3480fca4e80fdef39/contracts/ClaimManagement.sol#L176\n\nthe claim is taken by `_coverPool, _nonce, _index`, however caller may send incorrect indexes to the method.\n\nAt the line https://github.com/CoverProtocol/cover-core-v2/blob/513f5e502a8e8a623729c2c3480fca4e80fdef39/contracts/ClaimManagement.sol#L114 even the flow with invalid claim will pass the require condition and go to \n```solidity\nclaim.state = ClaimState.Validated;\n_resetCoverPoolClaimFee(_coverPool);\n```\nthis is unexpected behavior and potentially can lead to the contract misfunctioning.\n\n##### Recommendation\nAdd `require(_index < coverPoolClaims[_coverPool][_nonce].length, \"bad indexes\")`\n", + "protocol": "Cover Protocol", + "report_date": "2021-02-25", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Cover%20Protocol/Cover%20Protocol%20V2/README.md#2-lack-of-claim-validation", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Cover%20Protocol/Cover%20Protocol%20V2/Cover%20Protocol%20v2%20Security%20Audit%20Report.pdf" + }, + { + "title": "Unfair withdrawn amount", + "content": "##### Description\nHow to reproduce bug:\n - Deposit N tokens from Alice\n - Deposit N tokens from Bob\n - Deposit N tokens from Eve\n - Request and withdraw N tokens to Alice\n - Request and withdraw N tokens to Bob\n - Request and withdraw N tokens to Eve\n - At this point participant got different withdrawn amount(first lost more funds)\n\nDetailed explanation:\n - Use particular deflationary token as depositing asset https://gist.github.com/algys/eb905ec8efa41f80cf1eab57a3b31649\n - After all withdrawals Alice lost more funds than Eve, that behavior is unfair because they deposited same amount and just lost funds depending on withdrawal order\n\n##### Recommendation\nIt is recommended to refactor rebase logic and reduce amount of code duplication.\n", + "protocol": "Abyss Finance", + "report_date": "2021-02-24", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Abyss%20Finance/Abyss%20LockUp/README.md#1-unfair-withdrawn-amount", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Abyss%20Finance/Abyss%20LockUp/AbyssLockup%20Security%20Audit%20Report.pdf" + }, + { + "title": "Potential withdrawal lock and invalid distribution", + "content": "##### Description\nHow to reproduce bug:\n - Deposit N tokens from Alice\n - Deposit N tokens from Bob\n - Deposit N tokens from Eve\n - Send M (relatively huge amount) to Lockup contract directly (via transfer)\n - Request and withdraw N tokens to Alice\n - Request and withdraw N tokens to Bob\n - Request and withdraw N tokens to Eve\n - At this point participant got different withdrawn amount(first lost more funds), and depending on M amount sometimes contract can be failed on `request` call\n\nDetailed explanation:\n - Use particular deflationary token as depositing asset https://gist.github.com/algys/eb905ec8efa41f80cf1eab57a3b31649\n - After all withdrawals Alice lost more funds than Eve, that behavior is unfair because they deposited same amount and just lost funds depending on withdrawal order\n\n##### Recommendation\nIt is recommended to fix rebase logic related to lockup balance based calculation\n", + "protocol": "Abyss Finance", + "report_date": "2021-02-24", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Abyss%20Finance/Abyss%20LockUp/README.md#2-potential-withdrawal-lock-and-invalid-distribution", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Abyss%20Finance/Abyss%20LockUp/AbyssLockup%20Security%20Audit%20Report.pdf" + }, + { + "title": "Incorrect events parameter", + "content": "##### Description\nAt the lines below:\n - https://github.com/sushiswap/bentobox/blob/c2e150b16b8764ebfe2e1e6e267ae14e10738065/contracts/LendingPair.sol#L252\n - https://github.com/sushiswap/bentobox/blob/c2e150b16b8764ebfe2e1e6e267ae14e10738065/contracts/LendingPair.sol#L267\n - https://github.com/sushiswap/bentobox/blob/c2e150b16b8764ebfe2e1e6e267ae14e10738065/contracts/LendingPair.sol#L282\n - https://github.com/sushiswap/bentobox/blob/c2e150b16b8764ebfe2e1e6e267ae14e10738065/contracts/LendingPair.sol#L291\n - https://github.com/sushiswap/bentobox/blob/c2e150b16b8764ebfe2e1e6e267ae14e10738065/contracts/LendingPair.sol#L306\n - https://github.com/sushiswap/bentobox/blob/c2e150b16b8764ebfe2e1e6e267ae14e10738065/contracts/LendingPair.sol#L321\n \nthere are places where we have events which require an affected user address as a parameter, however in these cases `msg.sender` is wrongly used as a parameter. These functions accept special `user` parameter that should be used in events instead of `msg.sender`. The issue marked as major since it can fatally affect the user's side code that is based on events.\n\n##### Recommendation\nWe suggest replacing `msg.sender` to `user`.\n", + "protocol": "SushiSwap", + "report_date": "2021-02-15", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/SushiSwap/BentoBox/README.md#1-incorrect-events-parameter", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/SushiSwap/BentoBox/Sushiswap%20Bentobox%20Smart%20Contract%20Audit%20(1).pdf" + }, + { + "title": "It is possible to process a non-existing array element or skip an array element", + "content": "##### Description\nAt the line https://github.com/Grandthrax/yearnV2-generic-lender-strat/blob/979ef2f0e5da39ca59a5907c37ba2064fcd6be82/contracts/Strategy.sol#L424 is working with the elements of the `_newPositions` array in a loop.\nFor each element of the `lenders` array, there must be an element of the`_newPositions` array. But now the iteration of elements for the `_newPositions` array is not done correctly.\nThis will cause the `manualAllocation()` function to work incorrectly.\n\n##### Recommendation\nIt is necessary to correct the index value for the `_newPositions` array:\n\n`if (address(lenders[j]) == _newPositions[i].lender) {`\n\n", + "protocol": "Yearn Finance", + "report_date": "2021-02-15", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/Generic%20Lender/README.md#1-it-is-possible-to-process-a-non-existing-array-element-or-skip-an-array-element", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/Generic%20Lender/Yearn%20Generic%20Lender%20SCA.pdf" + }, + { + "title": "Ignore failure status for `CToken`", + "content": "##### Description\nThere are many reasons for failure `CToken`, but Lenders contracts ignore it in the all places.\nInterface methods of `CToken`:\nFor \n```\nfunction mint(uint256 mintAmount) external returns (uint256);\n```\n- https://github.com/Grandthrax/yearnV2-generic-lender-strat/blob/979ef2f0e5da39ca59a5907c37ba2064fcd6be82/contracts/GenericLender/GenericCompound.sol#L140\n- https://github.com/Grandthrax/yearnV2-generic-lender-strat/blob/979ef2f0e5da39ca59a5907c37ba2064fcd6be82/contracts/GenericLender/GenericCream.sol#L119\n\nFor \n```\nfunction redeemUnderlying(uint256 redeemAmount) external returns (uint256);\n```\n- https://github.com/Grandthrax/yearnV2-generic-lender-strat/blob/979ef2f0e5da39ca59a5907c37ba2064fcd6be82/contracts/GenericLender/GenericCompound.sol#L85\n- https://github.com/Grandthrax/yearnV2-generic-lender-strat/blob/979ef2f0e5da39ca59a5907c37ba2064fcd6be82/contracts/GenericLender/GenericCompound.sol#L113\n- https://github.com/Grandthrax/yearnV2-generic-lender-strat/blob/979ef2f0e5da39ca59a5907c37ba2064fcd6be82/contracts/GenericLender/GenericCompound.sol#L116\n\n- https://github.com/Grandthrax/yearnV2-generic-lender-strat/blob/979ef2f0e5da39ca59a5907c37ba2064fcd6be82/contracts/GenericLender/GenericCream.sol#L78\n- https://github.com/Grandthrax/yearnV2-generic-lender-strat/blob/979ef2f0e5da39ca59a5907c37ba2064fcd6be82/contracts/GenericLender/GenericCream.sol#L106\n- https://github.com/Grandthrax/yearnV2-generic-lender-strat/blob/979ef2f0e5da39ca59a5907c37ba2064fcd6be82/contracts/GenericLender/GenericCream.sol#L109\n\n\nReturn value (`uint256`) is enum of errors which may be:\n\n```\nenum Error {\n NO_ERROR,\n UNAUTHORIZED,\n COMPTROLLER_MISMATCH,\n INSUFFICIENT_SHORTFALL,\n INSUFFICIENT_LIQUIDITY,\n INVALID_CLOSE_FACTOR,\n INVALID_COLLATERAL_FACTOR,\n INVALID_LIQUIDATION_INCENTIVE,\n MARKET_NOT_ENTERED, // no longer possible\n MARKET_NOT_LISTED,\n MARKET_ALREADY_LISTED,\n MATH_ERROR,\n NONZERO_BORROW_BALANCE,\n PRICE_ERROR,\n REJECTION,\n SNAPSHOT_ERROR,\n TOO_MANY_ASSETS,\n TOO_MUCH_REPAY\n}\n```\n\n##### Recommendation\nWe recommend to validate return of every method for `CToken`. If method returns no `NO_ERROR` \u2014 revert it.\n", + "protocol": "Yearn Finance", + "report_date": "2021-02-15", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/Generic%20Lender/README.md#2-ignore-failure-status-for-ctoken", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/Generic%20Lender/Yearn%20Generic%20Lender%20SCA.pdf" + }, + { + "title": "It is possible to carry out attacks to manipulate pools within one transaction using a flash loan", + "content": "##### Description\nIn contracts https://github.com/CoverProtocol/cover-peripheral/tree/d5b37e34d47abec3252cdabd46e55e34a72421d4/contracts/CoverRouter.sol and https://github.com/CoverProtocol/cover-peripheral/tree/d5b37e34d47abec3252cdabd46e55e34a72421d4/contracts/Rollover.sol, any user can exchange tokens with a contract. Any user can add and remove liquidity. An attacker can take a flash loan and perform multiple liquidity manipulations within a single transaction. These manipulations can lead to a loss of funds for other users.\n\n##### Recommendation\nIt is recommended to add protection against token manipulation with flash loans.\nHere's some sample code:\n\n```solidity\nmapping(address => uint256) private _lastSwapBlock;\n\nfunction some() external {\n _preventSameTxOrigin();\n ....\n some logic\n ...\n }\n\nfunction _preventSameTxOrigin() private {\n require(block.number > _lastSwapBlock[tx.origin], \"SAME_TX_ORIGIN\");\n _lastSwapBlock[tx.origin] = block.number;\n }\n```\n", + "protocol": "Cover Protocol", + "report_date": "2021-01-11", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Cover%20Protocol/Cover%20Protocol%20Peripheral/README.md#1-it-is-possible-to-carry-out-attacks-to-manipulate-pools-within-one-transaction-using-a-flash-loan", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Cover%20Protocol/Cover%20Protocol%20Peripheral/Cover%20Protocol%20Peripheral%20Security%20Audit%20Report.pdf" + }, + { + "title": "Possibility to steal tokens from the contract balance", + "content": "##### Description\nMethod `addCoverAndCreatePools` defined at https://github.com/CoverProtocol/cover-peripheral/tree/d5b37e34d47abec3252cdabd46e55e34a72421d4/contracts/CoverRouter.sol#L128 accepts `_protocol` and `_collateral` addresses as arguments, then call `_addCover` that makes approve for `_protocol` an unlimited amount of `_collateral` tokens and call `_protocol.addCover`. There are no checks of `_protocol` and `_collateral` validity, so an attacker can pass malicious `_protocol` and get unlimited approval of `_collateral` tokens:\n```solidity\nif (_token.allowance(address(this), _spender) < _amount) {\n _token.approve(_spender, uint256(-1));\n}\n```\n\nAccording to the contract logic in an optimistic flow a contract shouldn't have any tokens in balance, but this invariant not fully checked, e.g. if `_protocol.addCover` at https://github.com/CoverProtocol/cover-peripheral/tree/d5b37e34d47abec3252cdabd46e55e34a72421d4/contracts/Rollover.sol#L75 fails and returns false, then the transaction will be executed successfully, but the user's funds will be left on the CoverRouter balance.\n\n##### Recommendation\nWe recommend to not use unlimited approve and add particular checks to keep the zero balance invariant.\n", + "protocol": "Cover Protocol", + "report_date": "2021-01-11", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Cover%20Protocol/Cover%20Protocol%20Peripheral/README.md#2-possibility-to-steal-tokens-from-the-contract-balance", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Cover%20Protocol/Cover%20Protocol%20Peripheral/Cover%20Protocol%20Peripheral%20Security%20Audit%20Report.pdf" + }, + { + "title": "Invalid setter function", + "content": "##### Description\n* In the `setDefaultController()` function defined at line https://github.com/pie-dao/ExperiPie/blob/facf3c246d9c43f5b1e0bad7dc2b0a9a2a2393c5/contracts/factories/PieFactoryContract.sol#L34, the new value is assigned to the `defaultController` variable. But it is not taken into account that earlier using the `bakePie()` function, the pool owner could be changed to address of `defaultController`. Thus, as a result of the work of the `setDefaultController()` function, the pool owner will remain the same, while it is expected that the pool will be managed from a different address.\n* In the `setFeeBeneficiary()` function defined at line https://github.com/pie-dao/ExperiPie/blob/facf3c246d9c43f5b1e0bad7dc2b0a9a2a2393c5/contracts/facets/Basket/BasketFacet.sol#L87 , the `LibBasketStorage.basketStorage().FeeBeneficiary` variable is assigned a new value. But it is not taken into account that earlier tokens could be issued to this address in the following places: https://github.com/pie-dao/ExperiPie/blob/facf3c246d9c43f5b1e0bad7dc2b0a9a2a2393c5/contracts/facets/Basket/BasketFacet.sol#L141, https://github.com/pie-dao/ExperiPie/blob/facf3c246d9c43f5b1e0bad7dc2b0a9a2a2393c5/contracts/facets/Basket/BasketFacet.sol#L175, https://github.com/pie-dao/ExperiPie/blob/facf3c246d9c43f5b1e0bad7dc2b0a9a2a2393c5/contracts/facets/Basket/BasketFacet.sol#L216.\n\n\n##### Recommendation\nIt is necessary to carefully check the logic of these functions and make corrections if necessary.\n", + "protocol": "PieDAO", + "report_date": "2020-12-11", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/PieDAO/ExperiPie/README.md#1-invalid-setter-function", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/PieDAO/ExperiPie/PieDAO%20Experipie%20Security%20Audit%20Report.pdf" + }, + { + "title": "Incorrect logic when burning and minting tokens", + "content": "##### Description\n* The `mint()` function defined at the line https://github.com/pie-dao/ExperiPie/blob/facf3c246d9c43f5b1e0bad7dc2b0a9a2a2393c5/contracts/facets/ERC20/ERC20Facet.sol#L44 is for minting new tokens.\nThe amount of tokens is increased on the wallet with the address `_receiver`.\nBut the ERC-20 specification also uses the value of the `totalSupply` variable.\nThis variable is not incremented here.\n\n* At line: https://github.com/pie-dao/ExperiPie/blob/facf3c246d9c43f5b1e0bad7dc2b0a9a2a2393c5/contracts/facets/ERC20/ERC20Facet.sol#L48. The `burn()` function is for burning tokens. The amount of tokens is reduced on the wallet with the address `_from`.\nBut the ERC-20 specification also uses the value of the `totalSupply` variable. The value of this variable is not decremented here.\nAt the same time, the value of the variable `totalSupply` is used 7 times for calculations in this smart contract: \nhttps://github.com/pie-dao/ExperiPie/blob/facf3c246d9c43f5b1e0bad7dc2b0a9a2a2393c5/contracts/facets/Basket/BasketFacet.sol.\n\n##### Recommendation\nThis problem needs to be corrected so that the calculations would be correct.\n", + "protocol": "PieDAO", + "report_date": "2020-12-11", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/PieDAO/ExperiPie/README.md#2-incorrect-logic-when-burning-and-minting-tokens", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/PieDAO/ExperiPie/PieDAO%20Experipie%20Security%20Audit%20Report.pdf" + }, + { + "title": "Approve / TransferFrom multiple withdrawal attack", + "content": "##### Description\nThis known issue is documented here: https://github.com/ethereum/EIPs/issues/738.\n\nSummary / example of the attack:\n1.\tAlice allows Bob to transfer N of Alice's tokens (N>0) by calling approve method on Token smart contract passing Bob's address and N as method arguments\n2.\tAfter some time, Alice decides to change from N to M (M>0) the number of Alice's tokens Bob is allowed to transfer, so she calls approve method again, this time passing Bob's address and M as method arguments\n3.\tBob notices Alice's second transaction before it was mined and quickly sends another transaction that calls transferFrom method to transfer N Alice's tokens somewhere\n4.\tIf Bob's transaction is be executed before Alice's transaction, then Bob will successfully transfer N Alice's tokens and will gain an ability to transfer another M tokens\n5.\tBefore Alice noticed that something went wrong, Bob calls transferFrom method again, this time to transfer M Alice's tokens.\n\nSo, Alice's attempt to change Bob's allowance from N to M (N>0 and M>0) made it possible for Bob to transfer N+M of Alice's tokens, while Alice never wanted to allow so many of her tokens to be transferred by Bob.\n\n##### Recommendation\nWe recommend adding additional sanity checks to the `approve()` function and using the `increaseAllowance()` / `decreaseAllowance ()` workaround functions:\n`require((_amount == 0) || (allowed[msg.sender][_spender] == 0));`\n", + "protocol": "PieDAO", + "report_date": "2020-12-11", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/PieDAO/ExperiPie/README.md#3-approve-transferfrom-multiple-withdrawal-attack", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/PieDAO/ExperiPie/PieDAO%20Experipie%20Security%20Audit%20Report.pdf" + }, + { + "title": "Gas overflow during iteration (DoS)", + "content": "##### Description\nEach iteration of the cycle requires a gas flow.\nA moment may come when more gas is required than it is allocated to record one block. In this case, all iterations of the loop will fail.\nAffected lines:\n* https://github.com/pie-dao/ExperiPie/blob/facf3c246d9c43f5b1e0bad7dc2b0a9a2a2393c5/contracts/factories/PieFactoryContract.sol#L72\n* https://github.com/pie-dao/ExperiPie/blob/facf3c246d9c43f5b1e0bad7dc2b0a9a2a2393c5/contracts/facets/Call/CallFacet.sol#L43\n* https://github.com/pie-dao/ExperiPie/blob/facf3c246d9c43f5b1e0bad7dc2b0a9a2a2393c5/contracts/facets/Call/CallFacet.sol#L67\n* https://github.com/pie-dao/ExperiPie/blob/facf3c246d9c43f5b1e0bad7dc2b0a9a2a2393c5/contracts/facets/Call/CallFacet.sol#L81\n* https://github.com/pie-dao/ExperiPie/blob/facf3c246d9c43f5b1e0bad7dc2b0a9a2a2393c5/contracts/facets/Basket/BasketFacet.sol on lines 45, 126, 158, 274, 296\n\n##### Recommendation\nWe recommend adding a check for the maximum possible number of elements of the arrays.\n", + "protocol": "PieDAO", + "report_date": "2020-12-11", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/PieDAO/ExperiPie/README.md#4-gas-overflow-during-iteration-dos", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/PieDAO/ExperiPie/PieDAO%20Experipie%20Security%20Audit%20Report.pdf" + }, + { + "title": "Global Protection of malicious backward calls in raw methods execution", + "content": "##### Description\nAt the lines: https://github.com/pie-dao/ExperiPie/blob/0.0.2/contracts/callManagers/LendingManager/LendingManager.sol#L44, https://github.com/pie-dao/ExperiPie/blob/0.0.2/contracts/callManagers/LendingManager/LendingManager.sol#L70, https://github.com/pie-dao/ExperiPie/blob/0.0.2/contracts/callManagers/LendingManager/LendingManager.sol#L102, https://github.com/pie-dao/ExperiPie/blob/0.0.2/contracts/callManagers/LendingManager/LendingManager.sol#L114, https://github.com/pie-dao/ExperiPie/blob/0.0.2/contracts/callManagers/RSIManager.sol#94, https://github.com/pie-dao/ExperiPie/blob/0.0.2/contracts/callManagers/RSIManager.sol#131 anything can happen in target methods execution.\n\nWe expect one-way class methods execution-graph like:\n```\nA.method1 -> B.method2 -> C.method3\n```\nSo it is better to ensure it.\n\n##### Recommendation\nWith growing complexity and cross-dependency of SmartContracts such mistaken or malicious case can occure and it will not be easy to track. So it is better to place protection against unexpected calls, e.g. place a `totalCallsCount` class-level variable. Increase it every time, any class-method was called.\nAnd do something like:\n\n```\n totalCallsCountBefore = totalCallsCount;\n call(target, bytes)\n require(totalCallsCount == totalCallsCountBefore)\n```\n", + "protocol": "PieDAO", + "report_date": "2020-12-11", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/PieDAO/ExperiPie/README.md#5-global-protection-of-malicious-backward-calls-in-raw-methods-execution", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/PieDAO/ExperiPie/PieDAO%20Experipie%20Security%20Audit%20Report.pdf" + }, + { + "title": "Missing Leading 'F' in LIQUIDATION_BONUS_MASK in ReserveConfiguration.sol", + "content": "##### Description\n\nhttps://github.com/aave/protocol-v2/blob/f435b2fa0ac589852ca3dd6ae2b0fbfbc7079d54/contracts/libraries/configuration/ReserveConfiguration.sol#L18 \n\nOne leading `F` is missing in this mask.\n\n```solidity\nuint256 constant LIQUIDATION_BONUS_MASK = 0xFFFFFFF0000FFFFFFFF;\n```\n\nThis fact results in the corruption of four bits in the reserve factor field during the operations on the liquidation bonus field. `getLiquidationBonus` is also affected.\n\n##### Recommendation\n\nWe suggest fixing the mask. We also recommend adding tests for each `ReserveConfiguration` field which have other fields set to some values, perform some actions, restore the field to the original value and make sure that the entire mask is intact.\n", + "protocol": "AAVE", + "report_date": "2020-12-03", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/AAVE/protocol%20v2/README.md#missing-leading-f-in-liquidation_bonus_mask-in-reserveconfigurationsol", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/AAVE/protocol%20v2/report.pdf" + }, + { + "title": "Improper Bit-Length Validation in Reserve Configuration", + "content": "##### Description\n\nhttps://github.com/aave/protocol-v2/blob/f435b2fa0ac589852ca3dd6ae2b0fbfbc7079d54/contracts/libraries/configuration/ReserveConfiguration.sol#L46\n\nhttps://github.com/aave/protocol-v2/blob/f435b2fa0ac589852ca3dd6ae2b0fbfbc7079d54/contracts/libraries/configuration/ReserveConfiguration.sol#L63\n\nhttps://github.com/aave/protocol-v2/blob/f435b2fa0ac589852ca3dd6ae2b0fbfbc7079d54/contracts/libraries/configuration/ReserveConfiguration.sol#L84\n\nhttps://github.com/aave/protocol-v2/blob/f435b2fa0ac589852ca3dd6ae2b0fbfbc7079d54/contracts/libraries/configuration/ReserveConfiguration.sol#L106\n\nhttps://github.com/aave/protocol-v2/blob/f435b2fa0ac589852ca3dd6ae2b0fbfbc7079d54/contracts/libraries/configuration/ReserveConfiguration.sol#L128\n\nBit lengths of the provided values are not checked against bit lengths of the corresponding fields in the `data`.\n\nFor example, here\n\n```solidity\nfunction setLtv(ReserveConfiguration.Map memory self, uint256 ltv) internal pure {\n self.data = (self.data & LTV_MASK) | ltv;\n```\n\nproviding a value greater than `65535` as `ltv` will result in a corruption of the liquidation threshold field. \n\n##### Recommendation\nWe recommend making sure that passed values fit in the corresponding fields.\n", + "protocol": "AAVE", + "report_date": "2020-12-03", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/AAVE/protocol%20v2/README.md#improper-bit-length-validation-in-reserve-configuration", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/AAVE/protocol%20v2/report.pdf" + }, + { + "title": "Erroneous UserBalance Restriction in Withdrawal Validation", + "content": "##### Description\n\nhttps://github.com/aave/protocol-v2/blob/f435b2fa0ac589852ca3dd6ae2b0fbfbc7079d54/contracts/libraries/logic/ValidationLogic.sol#L68\n\nIt looks like `userBalance` is erroneously used instead of `amount`. This will result in overly strict restrictions on withdrawals. \n\n##### Recommendation\nWe suggest replacing the argument.\n", + "protocol": "AAVE", + "report_date": "2020-12-03", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/AAVE/protocol%20v2/README.md#erroneous-userbalance-restriction-in-withdrawal-validation", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/AAVE/protocol%20v2/report.pdf" + }, + { + "title": "Uninitialized `availableLiquidity` in Loan Size Calculation.", + "content": "##### Description\n\nhttps://github.com/aave/protocol-v2/blob/f435b2fa0ac589852ca3dd6ae2b0fbfbc7079d54/contracts/libraries/logic/ValidationLogic.sol#L200\n\nThe `vars.availableLiquidity` field is not initialized before usage.\n\n```solidity\n//calculate the max available loan size in stable rate mode as a percentage of the\n//available liquidity\nuint256 maxLoanSizeStable = vars.availableLiquidity.percentMul(maxStableLoanPercent);\n```\n##### Recommendation\nProper initialization should be added.\n", + "protocol": "AAVE", + "report_date": "2020-12-03", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/AAVE/protocol%20v2/README.md#uninitialized-availableliquidity-in-loan-size-calculation", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/AAVE/protocol%20v2/report.pdf" + }, + { + "title": "Decimals Mismatch in Reserve Configuration Update", + "content": "##### Description\nhttps://github.com/aave/protocol-v2/blob/f435b2fa0ac589852ca3dd6ae2b0fbfbc7079d54/contracts/lendingpool/LendingPoolConfigurator.sol#L533 \n\nChanging the decimals here will not automatically change the decimals either in the aToken or in the debt tokens.\n\n```solidity\nfunction setReserveDecimals(address asset, uint256 decimals) external onlyAaveAdmin {\n ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);\n\n currentConfig.setDecimals(decimals);\n\n pool.setConfiguration(asset, currentConfig.data);\n```\n\nAdditionally, the oracle must be updated simultaneously to consider the new value of the decimals. Otherwise, significant mispricing and liquidations may occur. \n##### Recommendation\nWe suggest removing this function. Alternatively, the change may be allowed only for inactive reserve and must be propagated to the tokens.\n", + "protocol": "AAVE", + "report_date": "2020-12-03", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/AAVE/protocol%20v2/README.md#decimals-mismatch-in-reserve-configuration-update", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/AAVE/protocol%20v2/report.pdf" + }, + { + "title": "Flawed Stable Debt Calculation Due to Timestamp Mismatch", + "content": "##### Description\nhttps://github.com/aave/protocol-v2/blob/f435b2fa0ac589852ca3dd6ae2b0fbfbc7079d54/contracts/libraries/logic/ReserveLogic.sol#L341-L347 \n\nValue `vars.previousStableDebt` calculated this way is actually the current stable debt and always equals to `vars.currentStableDebt`.\n\n```solidity\n//calculate the stable debt until the last timestamp update\nvars.cumulatedStableInterest = MathUtils.calculateCompoundedInterest(\n vars.avgStableRate,\n vars.stableSupplyUpdatedTimestamp\n);\n\nvars.previousStableDebt = vars.principalStableDebt.rayMul(vars.cumulatedStableInterest);\n```\n\nAs a result, the stable debt difference is not taken into account. Moreover, the processed stable debt increment is not recorded in any way.\n##### Recommendation\nOne possible solution is to treat `vars.principalStableDebt` as the previous stable debt and update `StableDebtToken`'s `_totalSupply` and `_totalSupplyTimestamp` after the operation.\n", + "protocol": "AAVE", + "report_date": "2020-12-03", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/AAVE/protocol%20v2/README.md#flawed-stable-debt-calculation-due-to-timestamp-mismatch", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/AAVE/protocol%20v2/report.pdf" + }, + { + "title": "Overestimation of Liquidity in Interest Rate Update.", + "content": "##### Description\nhttps://github.com/aave/protocol-v2/blob/f435b2fa0ac589852ca3dd6ae2b0fbfbc7079d54/contracts/lendingpool/LendingPool.sol#L582\n\n```solidity\nIERC20(asset).safeTransferFrom(receiverAddress, vars.aTokenAddress, vars.amountPlusPremium);\n\nreserve.updateState();\nreserve.cumulateToLiquidityIndex(IERC20(vars.aTokenAddress).totalSupply(), vars.premium);\nreserve.updateInterestRates(asset, vars.aTokenAddress, vars.premium, 0);\n```\n\nhttps://github.com/aave/protocol-v2/blob/f435b2fa0ac589852ca3dd6ae2b0fbfbc7079d54/contracts/lendingpool/LendingPoolCollateralManager.sol#L521\n\n```solidity\nIERC20(toAsset).safeTransferFrom(\n receiverAddress,\n address(vars.toReserveAToken),\n vars.amountToReceive\n);\n\nif (vars.toReserveAToken.balanceOf(msg.sender) == 0) {\n _usersConfig[msg.sender].setUsingAsCollateral(toReserve.id, true);\n}\n\nvars.toReserveAToken.mint(msg.sender, vars.amountToReceive, toReserve.liquidityIndex);\ntoReserve.updateInterestRates(\n toAsset,\n address(vars.toReserveAToken),\n vars.amountToReceive,\n 0\n);\n```\n\n`updateInterestRates` needs to be called with `liquidityAdded` set to `0` since liquidity was already transferred to the pool's balance. Otherwise, overestimated liquidity would lead to too low debt interest rates.\n\n##### Recommendation\n\nIt is recommended to call `updateInterestRates` with `liquidityAdded` set to `0`.\n", + "protocol": "AAVE", + "report_date": "2020-12-03", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/AAVE/protocol%20v2/README.md#overestimation-of-liquidity-in-interest-rate-update", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/AAVE/protocol%20v2/report.pdf" + }, + { + "title": "Interest Rate Miscalculation Due to Stale Debt Values", + "content": "##### Description\n\nhttps://github.com/aave/protocol-v2/blob/f435b2fa0ac589852ca3dd6ae2b0fbfbc7079d54/contracts/lendingpool/LendingPoolCollateralManager.sol#L227-L232\n\n```solidity\nprincipalReserve.updateInterestRates(\n principal,\n principalReserve.aTokenAddress,\n vars.actualAmountToLiquidate,\n 0\n);\n\nif (vars.userVariableDebt >= vars.actualAmountToLiquidate) {\n IVariableDebtToken(principalReserve.variableDebtTokenAddress).burn(\n user,\n vars.actualAmountToLiquidate,\n principalReserve.variableBorrowIndex\n );\n} else {\n IVariableDebtToken(principalReserve.variableDebtTokenAddress).burn(\n user,\n vars.userVariableDebt,\n principalReserve.variableBorrowIndex\n );\n\n IStableDebtToken(principalReserve.stableDebtTokenAddress).burn(\n user,\n vars.actualAmountToLiquidate.sub(vars.userVariableDebt)\n );\n}\n```\n\nhttps://github.com/aave/protocol-v2/blob/f435b2fa0ac589852ca3dd6ae2b0fbfbc7079d54/contracts/lendingpool/LendingPoolCollateralManager.sol#L409-L414\n\n```solidity\ndebtReserve.updateInterestRates(\n principal,\n vars.principalAToken,\n vars.actualAmountToLiquidate,\n 0\n);\nIERC20(principal).safeTransferFrom(receiver, vars.principalAToken, vars.actualAmountToLiquidate);\n\nif (vars.userVariableDebt >= vars.actualAmountToLiquidate) {\n IVariableDebtToken(debtReserve.variableDebtTokenAddress).burn(\n user,\n vars.actualAmountToLiquidate,\n debtReserve.variableBorrowIndex\n );\n} else {\n IVariableDebtToken(debtReserve.variableDebtTokenAddress).burn(\n user,\n vars.userVariableDebt,\n debtReserve.variableBorrowIndex\n );\n IStableDebtToken(debtReserve.stableDebtTokenAddress).burn(\n user,\n vars.actualAmountToLiquidate.sub(vars.userVariableDebt)\n );\n}\n```\n\nDebt reserve interest rates are updated before debt burning takes place.\n\nAs a result, stale total debt values are used during interest rates calculation. \n\n##### Recommendation\nWe suggest switching `updateInterestRates` and the `if` statement.\n", + "protocol": "AAVE", + "report_date": "2020-12-03", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/AAVE/protocol%20v2/README.md#interest-rate-miscalculation-due-to-stale-debt-values", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/AAVE/protocol%20v2/report.pdf" + }, + { + "title": "Inaccurate `liquidityAdded` Parameter Before Flashloan Transfer", + "content": "##### Description\n\nhttps://github.com/aave/protocol-v2/blob/56d25e81cb0fdfcac785d669d3577b1ef2d9286e/contracts/lendingpool/LendingPool.sol#L511\n\nThe `liquidityAdded` parameter of the `updateInterestRates` call seems to be incorrect as the flashloan body is yet to be transferred thus it will not be included in the interest rates calculation.\n\n##### Recommendation\n\nIt is recommended to fix the `liquidityAdded` parameter.\n", + "protocol": "AAVE", + "report_date": "2020-12-03", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/AAVE/protocol%20v2/README.md#inaccurate-liquidityadded-parameter-before-flashloan-transfer", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/AAVE/protocol%20v2/report.pdf" + }, + { + "title": "Potential withdrawal lock", + "content": "##### Description\nAt this line: https://github.com/iearn-finance/yearn-vaults/blob/054034304c7912d227d460feadc23177103de0b9/contracts/Vault.vy#L787\n\n```solidity\namountNeeded: uint256 = value - self.token.balanceOf(self)\n```\n\nIn case if the result of withdrawals in the previous loop iteration `self.token.balanceOf(self)` becomes more than `value` that will cause a transaction revert. That scenario is possible because only for the first iteration we can exactly consider that `value` more than `self.token.balanceOf(self)`, but according to the withdrawal logic there is no check for the following iterations that the real withdrawn amount(after `Strategy(strategy).withdraw(amountNeeded)` call) is less or equal to what is desired `amountNeeded`.\n\n##### Recommendation\nIt seems in normal/optimistic flow that `Strategy(strategy).withdraw(amountNeeded)` never withdraws more tokens than requested, but anyway we recommend properly handling a pessimistic case because strategy is an external contract and can be broken. Due to withdrawal queue, it can be changed only by governance (usually governance is msig or smth like that). Unexpected strategy behavior can lock withdrawals for undefined period that might be fatal in some cases.\n", + "protocol": "Yearn Finance", + "report_date": "2020-12-02", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/Vault%20V2%20(Vyper%20part)/README.md#1-potential-withdrawal-lock", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Yearn%20Finance/Vault%20V2%20(Vyper%20part)/Yearn%20Finance%20Vault%20v.2%20(Vyper%20part)%20Security%20Audit%20Report.pdf" + }, + { + "title": "Potential claiming stuck for several periods after withdraw", + "content": "\nhttps://github.com/defistarter/contracts/blob/9ffe009ee6047ced669711dde14fe38483abdf7e/StakingPool.sol#L341\n\nHere we have division by `periodTotalSupply`, in case if `periodTotalSupply` becomes zero that it will be impossible to claim any reward.\n\nAttack flow:\n\n*Assuming that we have 1 user and 5 periods.*\n\n- at period 0: user stake 10 tokens (`_historyTotalSupply[0]` = `10`, `user.period` = `0`)\n- at period 1: user claimReward and withdraw all 10 tokens (`_historyTotalSupply[1]` = `0`, `user.period` = `1`)\n- at period 2: do nothing (`_historyTotalSupply[2]` = `0`, `user.period` = `1`)\n- at period 3: user stake 20 tokens (`_historyTotalSupply[3]` = `20`, `user.period` = `1`)\n- at period 4: user try to `claimReward` and get error \u201cSafeMath: division by zero\u201d\n\n- contract state at period 4 is:\n\n - `_historyTotalSupply` = `[10, 0, 0, 20, 0]`\n - `user.period` = `1`\n\n so if user try to claimReward we will get:\n - `savedTotalSupply` = `0` (https://github.com/defistarter/contracts/blob/9ffe009ee6047ced669711dde14fe38483abdf7e/StakingPool.sol#L326)\n - `periodTotalSupply` = `0` (https://github.com/defistarter/contracts/blob/9ffe009ee6047ced669711dde14fe38483abdf7e/StakingPool.sol#L333)\n\n and finally here we have division by zero here: https://github.com/defistarter/contracts/blob/9ffe009ee6047ced669711dde14fe38483abdf7e/StakingPool.sol#L341\n\nWe recommend to check the `periodTotalSupply` value before division and omit that in case of zero.\n\nThis particular issue is not marked as critical because that cannot be exploited to steal funds, but issues should be fixed ASAP due to that can break desired contract logic.\n\nStatus: *Fixed at https://github.com/defistarter/contracts/commit/670678d7d2fd01b4c059ab76535c849f556377b4, https://github.com/defistarter/contracts/commit/07edefa4c5931e5fbef97c61d48062c606fc21c4*\n\n", + "protocol": "Defi Starter", + "report_date": "2020-11-06", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Defi%20Starter/DefiStarter%20Smart%20Contracts/README.md#1-potential-claiming-stuck-for-several-periods-after-withdraw", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Defi%20Starter/DefiStarter%20Smart%20Contracts/report.pdf" + }, + { + "title": "Collision of storage layouts of TokenProxy and AkropolisToken", + "content": " \nThe problem is illustrated by the `test/TestProxySlotCollision.js` (works for commit 3ad8eaa6f2849dceb125c8c614d5d61e90d465a2).\n \nAs can be shown, a collision is almost completely avoided because `paused` and `locked` flags were packed by the solidity compiler and don't collide with other fields, as well as the slot for whitelist not being used (because mappings are implemented in such way). But there is collision of `bool whitelisted` and `decimals` fields.\n \nA simple solution is to use \"unique\" slot locations for each field (except shared base contract fields) derived via `keccak256`, for example: https://github.com/poanetwork/poa-network-consensus-contracts/blob/0c175cb98dac52201342f4e5e617f89a184dd467/contracts/KeysManager.sol#L185.\nIn this case we also recommend that the contract name into hash function invocation is included, and the use of `abi.encode` in place of `abi.encodePacked`, like this: `uintStorage[keccak256(abi.encode(\"TokenProxy\", \"decimals\"))] = decimals`.\n \nFixed in [79565a3](https://github.com/akropolisio/AkropolisToken/commit/79565a351c74d7fc668ef96927a68876521e37df)\n ", + "protocol": "Akropolis", + "report_date": "2019-07-07", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/Akropolis/Token/README.md#1-collision-of-storage-layouts-of-tokenproxy-and-akropolistoken", + "pdf_link": "https://github.com/mixbytes/audits_public/blob/master/Akropolis/Token/Akropolis%20Token%20Smart%20Contract%20Audit%20Report.pdf" + }, + { + "title": "https://github.com/kickico/contracts/blob/abd93bcce948071af24dad4c35439202abf92b7c/src/token.sol#L363", + "content": "Function: function issue(address _to, uint256 _amount) public onlyOwner validAddress(_to) notThis(_to)\n\nMissed call to addIndex(_to) will result in token losses by investors\n\n", + "protocol": "KickICO", + "report_date": "2017-09-04", + "impact": "HIGH", + "finders": [], + "github_link": "https://github.com/mixbytes/audits_public/blob/master/KickICO/README.md#1-httpsgithubcomkickicocontractsblobabd93bcce948071af24dad4c35439202abf92b7csrctokensoll363", + "pdf_link": null + } +]