Basin - erebus's results

A composable EVM-native decentralized exchange protocol.

General Information

Platform: Code4rena

Start Date: 03/07/2023

Pot Size: $40,000 USDC

Total HM: 14

Participants: 74

Period: 7 days

Judge: alcueca

Total Solo HM: 9

Id: 259

League: ETH

Basin

Findings Distribution

Researcher Performance

Rank: 4/74

Findings: 3

Award: $2,177.78

QA:
grade-a
Gas:
grade-b

🌟 Selected for report: 1

πŸš€ Solo Findings: 1

Findings Information

🌟 Selected for report: erebus

Labels

bug
2 (Med Risk)
grade-a
satisfactory
selected for report
sponsor acknowledged
upgraded by judge
edited-by-warden
M-13

Awards

2152.3705 USDC - $2,152.37

External Links

Useless modifier in consructor here (even the constructor is empty, just why the modifier there, it makes no sense)

Bad assumptions to calculate the number of block passed here. BLOCK_TIME is an immutable variable which is passed as a parameter to the constructor. However, with future updates to the Ethereum protocol (IDK, reth or other validation algorithm) which could reduce that number would mean that functions dependant on that to work incorrectly like readInstantaneousReserves or _readCumulativeReserves. Do not assume the block rate to remain constant in the future or implement some function that modifies the BLOCK_TIME every T seconds/minutes/whatever

#1 - c4-judge

2023-08-04T20:56:09Z

alcueca marked the issue as grade-a

#2 - c4-judge

2023-08-05T21:44:07Z

alcueca changed the severity to 2 (Med Risk)

#3 - c4-judge

2023-08-05T21:44:08Z

alcueca changed the severity to 2 (Med Risk)

#4 - c4-judge

2023-08-05T21:44:26Z

alcueca marked the issue as satisfactory

#5 - c4-sponsor

2023-09-28T12:15:18Z

publiuss (sponsor) acknowledged

#6 - publiuss

2023-09-28T12:18:21Z

First QA item is acknowledged. The modifier is there to initialize the ReentrancyGuard contract. Imo, its cleaner to have an empty constructor than to have no constructor and have the user realize that it uses the ReentrancyGuard modifier by defualt. This item is a duplicate of other QA reports.

Second QA item is a duplicate of: https://github.com/code-423n4/2023-07-basin-findings/issues/176. See comment on issue for remediation status.

Lines of code

https://github.com/code-423n4/2023-07-basin/blob/f15fe66d57c2f226c232685d16f297e54bcc0939/src/libraries/LibWellConstructor.sol#L71-L81

Vulnerability details

Impact

Writing this

string memory name = LibContractInfo.getSymbol(address(_tokens[0]));
string memory symbol = name;

does not copy the content of name in symbol, what it does is copy the POINTER to the place where the name is stored. Thus, one change in one of them leads to the other pointing to the "updated" variable, breaking the working process of the function and passing wrong arguments to the init function (so the high severity`

Proof of Concept

From Jean Cvllr awesome tutorials about data locations we have

In reality, what happened under the hood is that we create two pointers to memory, named by the variables data and greetings. When we do data = greetings , we think we are assigning the value cafecafe to the variable data. But we are not assigning anything at all here! We are giving the following instruction to the EVM: β€œvariable data, I order you to point to the same location in memory that the variable greetings point to!”

(you can read the Yellow paper too but the above is more user-friendly). That means the next code does the same to the two variables because both point to the same place, so one change will affect the other the same way

for (uint256 i = 1; i < _tokens.length; ++i) {
        name = string.concat(name, ":", LibContractInfo.getSymbol(address(_tokens[i])));
        symbol = string.concat(symbol, LibContractInfo.getSymbol(address(_tokens[i])));
}
name = string.concat(name, " ", LibContractInfo.getName(_wellFunction.target), " Well");
symbol = string.concat(symbol, LibContractInfo.getSymbol(_wellFunction.target), "w");

Because of that, the initFunctionCall = abi.encodeWithSignature("init(string,string)", name, symbol); is broken given the fact that name and symbol are the same.

Tools Used

Manual analysis

Use local variables instead of memory references/pointers

Assessed type

Error

#0 - c4-pre-sort

2023-07-12T04:56:07Z

141345 marked the issue as low quality report

#1 - 141345

2023-07-13T09:30:02Z

need to recheck the POC validity

maybe QA is more appropriate

#2 - c4-pre-sort

2023-07-13T09:30:11Z

141345 marked the issue as duplicate of #199

#3 - c4-judge

2023-08-04T12:43:41Z

alcueca changed the severity to QA (Quality Assurance)

#4 - c4-judge

2023-08-19T18:39:51Z

alcueca marked the issue as grade-a

Awards

7.8853 USDC - $7.89

Labels

bug
G (Gas Optimization)
grade-b
low quality report
edited-by-warden
G-27

External Links

Do not use full size words for low value variables (more if they are constant). Check here

Change strings in require to custom errors, saving gas on the way. The regex pattern is "\w*"\); and loop through the occurrences

Use unchecked { i++; } in loops where the end is known. The regex pattern is ; ?\w*\++. Save gas because solidity checks integers for over/underflow after 0.8.0 by default, so we can omit that because we know the limit

#0 - c4-pre-sort

2023-07-12T10:22:09Z

141345 marked the issue as low quality report

#1 - c4-judge

2023-08-05T10:52:13Z

alcueca marked the issue as grade-b

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax Β© 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter