Lack of zero-address validation on address parameters may lead to transaction reverts, waste gas, require resubmission of transactions and may even force contract redeployments in certain cases within the protocol.
approve() is subject to a known front-running attack. It is deprecated in favor of safeIncreaseAllowance() and safeDecreaseAllowance(). If only setting the initial allowance to the value that means infinite, safeIncreaseAllowance() can be used instead.
Some tokens (like USDT L199) do not work when changing the allowance from an existing non-zero allowance value. They must first be approved by zero and then the actual allowance must be approved.
While floating pragmas make sense for libraries to allow them to be included with multiple different versions of applications, it may be a security risk for application implementations.
A known vulnerable compiler version may accidentally be selected or security tools might fall-back to an older compiler version ending up checking a different EVM compilation that is ultimately deployed on the blockchain.
It is recommended to pin to a concrete compiler version.
Proof Of Concept
All in-scope contracts use floating pragmas ^0.8.13 of Solidity
Summary
Low Risk Issues
approve()
Is Deprecatedapprove(0)
Firstconstructor
Total: 50 contexts over 4 issues
Non-critical Issues
require()
/revert()
Statements Should Have Descriptive Reason Stringsecrecover
is susceptible to signature malleabilityTotal: 94 contexts over 7 issues
Low Risk Issues
[LOW‑1] Missing Checks for Address(0x0)
Lack of zero-address validation on address parameters may lead to transaction reverts, waste gas, require resubmission of transactions and may even force contract redeployments in certain cases within the protocol.
Proof Of Concept
https://github.com/code-423n4/2022-10-inverse/tree/main/src/BorrowController.sol#L26
https://github.com/code-423n4/2022-10-inverse/tree/main/src/BorrowController.sol#L32
https://github.com/code-423n4/2022-10-inverse/tree/main/src/BorrowController.sol#L38
https://github.com/code-423n4/2022-10-inverse/tree/main/src/DBR.sol#L53
https://github.com/code-423n4/2022-10-inverse/tree/main/src/DBR.sol#L81
https://github.com/code-423n4/2022-10-inverse/tree/main/src/DBR.sol#L90
https://github.com/code-423n4/2022-10-inverse/tree/main/src/DBR.sol#L99
https://github.com/code-423n4/2022-10-inverse/tree/main/src/DBR.sol#L284
https://github.com/code-423n4/2022-10-inverse/tree/main/src/DBR.sol#L313
https://github.com/code-423n4/2022-10-inverse/tree/main/src/DBR.sol#L325
https://github.com/code-423n4/2022-10-inverse/tree/main/src/DBR.sol#L349
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Fed.sol#L48
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Fed.sol#L66
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L130
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L136
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L142
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L278
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L422
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L486
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L531
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L559
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L591
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Oracle.sol#L44
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Oracle.sol#L53
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Oracle.sol#L61
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Oracle.sol#L112
https://github.com/code-423n4/2022-10-inverse/tree/main/src/escrows/GovTokenEscrow.sol#L30
https://github.com/code-423n4/2022-10-inverse/tree/main/src/escrows/GovTokenEscrow.sol#L43
https://github.com/code-423n4/2022-10-inverse/tree/main/src/escrows/GovTokenEscrow.sol#L66
https://github.com/code-423n4/2022-10-inverse/tree/main/src/escrows/INVEscrow.sol#L44
https://github.com/code-423n4/2022-10-inverse/tree/main/src/escrows/INVEscrow.sol#L59
https://github.com/code-423n4/2022-10-inverse/tree/main/src/escrows/INVEscrow.sol#L90
https://github.com/code-423n4/2022-10-inverse/tree/main/src/escrows/SimpleERC20Escrow.sol#L36
Recommended Mitigation Steps
Consider adding explicit zero-address validation on input parameters of address type.
[LOW‑2] IERC20
approve()
Is Deprecatedapprove()
is subject to a known front-running attack. It is deprecated in favor ofsafeIncreaseAllowance()
andsafeDecreaseAllowance()
. If only setting the initial allowance to the value that means infinite,safeIncreaseAllowance()
can be used instead.https://docs.openzeppelin.com/contracts/3.x/api/token/erc20#IERC20-approve-address-uint256-
Proof Of Concept
https://github.com/code-423n4/2022-10-inverse/tree/main/src/escrows/INVEscrow.sol#L50
Recommended Mitigation Steps
Consider using
safeIncreaseAllowance()
/safeDecreaseAllowance()
instead.[LOW‑3] The Contract Should
approve(0)
FirstSome tokens (like USDT L199) do not work when changing the allowance from an existing non-zero allowance value. They must first be approved by zero and then the actual allowance must be approved.
Proof Of Concept
https://github.com/code-423n4/2022-10-inverse/tree/main/src/escrows/INVEscrow.sol#L50
Recommended Mitigation Steps
Approve with a zero amount first before setting the actual amount.
[LOW‑4] Missing parameter validation in
constructor
Some parameters of constructors are not checked for invalid values.
Proof Of Concept
https://github.com/code-423n4/2022-10-inverse/tree/main/src/BorrowController.sol#L14
https://github.com/code-423n4/2022-10-inverse/tree/main/src/DBR.sol#L36-L39
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Fed.sol#L39-L41
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L77-L86
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Oracle.sol#L32
Recommended Mitigation Steps
Validate the parameters.
Non Critical Issues
[NC‑1] Critical Changes Should Use Two-step Procedure
The critical procedures should be two step process.
See similar findings in previous Code4rena contests for reference: https://code4rena.com/reports/2022-06-illuminate/#2-critical-changes-should-use-two-step-procedure
Proof Of Concept
https://github.com/code-423n4/2022-10-inverse/tree/main/src/BorrowController.sol#L26
https://github.com/code-423n4/2022-10-inverse/tree/main/src/DBR.sol#L62
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Fed.sol#L48
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Fed.sol#L57
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Fed.sol#L66
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L118
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L124
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L130
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L136
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L142
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L149
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L161
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L172
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L183
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L194
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Oracle.sol#L53
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Oracle.sol#L61
Recommended Mitigation Steps
Lack of two-step procedure for critical operations leaves them error-prone. Consider adding two step procedure on the critical functions.
[NC‑2] Public Functions Not Called By The Contract Should Be Declared External Instead
Contracts are allowed to override their parents’ functions and change the visibility from external to public.
Proof Of Concept
https://github.com/code-423n4/2022-10-inverse/tree/main/src/BorrowController.sol#L26
https://github.com/code-423n4/2022-10-inverse/tree/main/src/BorrowController.sol#L32
https://github.com/code-423n4/2022-10-inverse/tree/main/src/BorrowController.sol#L38
https://github.com/code-423n4/2022-10-inverse/tree/main/src/DBR.sol#L62
https://github.com/code-423n4/2022-10-inverse/tree/main/src/DBR.sol#L81
https://github.com/code-423n4/2022-10-inverse/tree/main/src/DBR.sol#L90
https://github.com/code-423n4/2022-10-inverse/tree/main/src/DBR.sol#L99
https://github.com/code-423n4/2022-10-inverse/tree/main/src/DBR.sol#L215
https://github.com/code-423n4/2022-10-inverse/tree/main/src/DBR.sol#L284
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Fed.sol#L48
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Fed.sol#L57
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Fed.sol#L66
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Fed.sol#L75
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Fed.sol#L86
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Fed.sol#L103
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Fed.sol#L131
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L118
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L124
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L130
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L136
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L142
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L149
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L161
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L172
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L183
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L194
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L212
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L258
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L267
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L278
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L408
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L422
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L472
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L486
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L531
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L546
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L559
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L591
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Oracle.sol#L53
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Oracle.sol#L61
[NC‑3] Missing event for critical parameter change
When changing state variables events are not emitted. Emitting events allows monitoring activities with off-chain monitoring tools.
Proof Of Concept
https://github.com/code-423n4/2022-10-inverse/tree/main/src/BorrowController.sol#L26
https://github.com/code-423n4/2022-10-inverse/tree/main/src/DBR.sol#L53
https://github.com/code-423n4/2022-10-inverse/tree/main/src/DBR.sol#L62
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Fed.sol#L48
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Fed.sol#L57
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Fed.sol#L66
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L118
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L124
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L130
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L136
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L142
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L149
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L161
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L172
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L183
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L194
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Oracle.sol#L44
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Oracle.sol#L53
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Oracle.sol#L61
[NC‑4]
require()
/revert()
Statements Should Have Descriptive Reason StringsProof Of Concept
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Fed.sol#L93
https://github.com/code-423n4/2022-10-inverse/tree/main/src/escrows/GovTokenEscrow.sol#L67
https://github.com/code-423n4/2022-10-inverse/tree/main/src/escrows/INVEscrow.sol#L91
[NC‑5] Implementation contract may not be initialized
OpenZeppelin recommends that the initializer modifier be applied to constructors. Per OZs Post implementation contract should be initialized to avoid potential griefs or exploits. https://forum.openzeppelin.com/t/uupsupgradeable-vulnerability-post-mortem/15680/5
Proof Of Concept
https://github.com/code-423n4/2022-10-inverse/tree/main/src/BorrowController.sol#L13
https://github.com/code-423n4/2022-10-inverse/tree/main/src/DBR.sol#L30-L35
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Oracle.sol#L29-L31
https://github.com/code-423n4/2022-10-inverse/tree/main/src/escrows/INVEscrow.sol#L34
[NC‑6] Avoid Floating Pragmas: The Version Should Be Locked
Avoid floating pragmas for non-library contracts.
While floating pragmas make sense for libraries to allow them to be included with multiple different versions of applications, it may be a security risk for application implementations.
A known vulnerable compiler version may accidentally be selected or security tools might fall-back to an older compiler version ending up checking a different EVM compilation that is ultimately deployed on the blockchain.
It is recommended to pin to a concrete compiler version.
Proof Of Concept
All in-scope contracts use floating pragmas ^0.8.13 of Solidity
[NC‑7] Use of
ecrecover
is susceptible to signature malleabilityThe built-in EVM precompile
ecrecover
is susceptible to signature malleability, which could lead to replay attacks. References: https://swcregistry.io/docs/SWC-117, https://swcregistry.io/docs/SWC-121, and https://medium.com/cryptronics/signature-replay-vulnerabilities-in-smart-contracts-3b6f7596df57. While this is not immediately exploitable, this may become a vulnerability if used elsewhere.Proof Of Concept
https://github.com/code-423n4/2022-10-inverse/tree/main/src/DBR.sol#L226
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L425
https://github.com/code-423n4/2022-10-inverse/tree/main/src/Market.sol#L489
Recommended Mitigation Steps
Consider using OpenZeppelin’s ECDSA library (which prevents this malleability) instead of the built-in function. https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/ECDSA.sol