Platform: Code4rena
Start Date: 25/10/2022
Pot Size: $50,000 USDC
Total HM: 18
Participants: 127
Period: 5 days
Judge: 0xean
Total Solo HM: 9
Id: 175
League: ETH
Rank: 76/127
Findings: 1
Award: $36.73
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: 0x1f8b
Also found by: 0xNazgul, 0xSmartContract, Aymen0909, B2, Bnke0x0, Deivitto, Diana, Dinesh11G, ElKu, JC, Josiah, Rahoz, RaymondFam, ReyAdmirado, Rolezn, Waze, __141345__, adriro, aphak5010, brgltd, c3phas, c7e7eff, carlitox477, cducrest, ch0bu, chrisdior4, cryptonue, cryptostellar5, cylzxje, d3e4, delfin454000, enckrish, evmwanderer, fatherOfBlocks, gogo, hansfriese, horsefacts, immeas, leosathya, lukris02, neumo, oyc_109, pedr02b2, rbserver, robee, rotcivegaf, rvierdiiev, sakshamguruji, shark, simon135, tnevler, trustindistrust, wagmi
36.7345 USDC - $36.73
Market.getEscrow()
https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L245-L251
The function getEscrow()
called by deposit()
will execute the external call escrow.initialize()
before updating the state variable escrows[user]
. Consider updating the state before the external call to use the checks-effects-interactions pattern.
diff --git a/Market.sol.orig b/Market.sol --- a/Market.sol.orig +++ b/Market.sol function getEscrow(address user) internal returns (IEscrow) { if(escrows[user] != IEscrow(address(0))) return escrows[user]; + escrows[user] = escrow; IEscrow escrow = createEscrow(user); escrow.initialize(collateral, user); - escrows[user] = escrow; return escrow; }
https://github.com/code-423n4/2022-10-inverse/blob/main/src/BorrowController.sol#L47
tx.origin can be manipulated by malicious contracts calling into BorrowController
. Consider removing tx.origin for authorization and using a pattern where msg.sender
is set during initalization and verified for later calls.
DBR.accrueDueTokens()
https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L286
Consider replacing lastUpdated[user] == block.timestamp
, with lastUpdated[user] <= block.timestamp
, to ensure that the current timestamp must be bigger the last update.
https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L77-L80
https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L130
https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L136
https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L142
If a variable gets configured with address zero, failure to immediately reset the value can result in unexpected behavior for the project.
https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L118
https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L124
https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L130
Lack of two-step procedure for critical operations leaves them error-prone. Consider adding two step procedure on the critical functions.
Consider adding a two-steps pattern on critical changes to avoid mistakenly transferring ownership of roles or critial functionalities to the wrong address.
Adding events will facilitate offchain monitoring
https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L130
https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L142
All the contracts in scope are floating the pragma version.
Consider locking the pragma to ensure that contracts do not accidentally get deployed using an outdated compiler version.
Note that pragma statements can be allowed to float when a contract is intended for consumption by other developers, as in the case with contracts in a library or a package.
https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L74
https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L149
Following instance is using uint256
https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L55
Following instance is using uint
https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L69
Consider using only one identifier throughout the codebase, e.g. only uint or only uint256.
The solidity documentation recommends the following order for functions:
constructor receive function (if exists) fallback function (if exists) external public internal private
Another recommendation from the style guide is related to declaring events before functions.
Consider adopting the following strategy throughout the codebase.
https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L245
https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L258
https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L258
https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L74-L76
https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L563-L564
https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L591
#0 - c4-judge
2022-11-08T00:39:57Z
0xean marked the issue as grade-b