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: 71/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
Check for address(0x0) is missing for operator
:
operator = _operator;
Also DBR.sol: L39 and Oracle.sol: L32
Check for address(0x0) is missing for gov
:
gov = _gov;
Also Fed.sol: L50 and Market.sol: L77
Check for address(0x0) is missing for chair
:
chair = _chair;
Also Fed.sol: L68
Check for address(0x0) is missing for beneficiary
:
beneficiary = _beneficiary;
Also INVEscrow.sol: L48
Checks for address(0x0) are also missing for lender
, pauseGuardian
, and escrowImplementation
:
lender = _lender; pauseGuardian = _pauseGuardian; escrowImplementation = _escrowImplementation;
@param newReplenishmentPriceBps_ The new replen
Change replen
to replenishment price
or whatever was intended
At 5000, 50% of of a borrower's underwater debt can be liquidated. Only callable by governance.
Remove repeated word of
@param amount The amount od DOLA to recall to the the lender.
Remove repeated word the
@param repaidDebt Th amount of user user debt to liquidate.
Change Th
to The
and remove repeated word user
@param deniedContract The addres of the denied contract
Change addres
to address
@notice Sets pending operator of the contract. Operator role must be claimed by the new oprator. Only callable by Operator.
Change oprator
to operator
@notice Removes a minter from the set of addresses allowe to mint DBR tokens. Only callable by Operator.
Change allowe
to allowed
@notice Get the DBR deficit of an address. Will return 0 if th user has zero DBR or more.
Change th
to the
@dev Collateral factor mus be set below 100%
Change mus
to must
@param _liquidationIncentiveBps The new liqudation incentive set in basis points. 1 = 0.01%
Change liqudation
to liquidation
@notice View function for getting the amount of liquidateable debt a user holds.
Change liquidateable
to liquidatable
In theory, comments over 80 characters should wrap using multi-line comment syntax. Even if somewhat longer comments (up to 120 characters) are acceptable and a scroll bar is provided, there are cases where very long comments interfere with readability. Below are five instances of extra-long comments (or groups of comments) whose readability could be improved, as shown:
@dev Markets can have more DOLA in them than they've been supplied, due to force replenishes. This call will revert if trying to contract more than have been supplied.
Suggestion:
@dev Markets can have more DOLA in them than they've been supplied, due to force replenishes. This call will revert if trying to contract more than have been supplied.
/** @title Oracle @notice Oracle used by markets. Can use both fixed price feeds and Chainlink-style feeds for prices. The Pessimistic Oracle introduces collateral factor into the pricing formula. It ensures that any given oracle price is dampened to prevent borrowers from borrowing more than the lowest recorded value of their collateral over the past 2 days. This has the advantage of making price manipulation attacks more difficult, as an attacker needs to log artificially high lows. It has the disadvantage of reducing borrow power of borrowers to a 2-day minimum value of their collateral, where the value must have been seen by the oracle. */
Suggestion:
/** @title Oracle @notice Oracle used by markets. Can use both fixed price feeds and Chainlink-style feeds for prices. The Pessimistic Oracle introduces collateral factor into the pricing formula. It ensures that any given oracle price is dampened to prevent borrowers from borrowing more than the lowest recorded value of their collateral over the past 2 days. This has the advantage of making price manipulation attacks more difficult, as an attacker needs to log artificially high lows. It has the disadvantage of reducing borrow power of borrowers to a 2-day minimum value of their collateral, where the value must have been seen by the oracle. */
This specific escrow is meant as an example of how an escrow can be implemented that allows depositors to delegate votes with their collateral, unlike pooled deposit protocols.
Suggestion:
This specific escrow is meant as an example of how an escrow can be implemented that allows depositors to delegate votes with their collateral, unlike pooled deposit protocols.
This escrow allows user to deposit INV collateral directly into the xINV contract, earning APY and allowing them to delegate votes on behalf of the xINV collateral
Suggestion:
This escrow allows user to deposit INV collateral directly into the xINV contract, earning APY and allowing them to delegate votes on behalf of the xINV collateral.
if(invBalance < amount) xINV.redeemUnderlying(amount - invBalance); // we do not check return value because next call will fail if this fails anyway
Suggestion:
// We do not check return value below because next call will fail if this fails anyway if(invBalance < amount) xINV.redeemUnderlying(amount - invBalance);
Comments that appear to refer to open items should be addressed.
/* Uncomment if Escrow contract should handle on deposit callbacks. This function should remain callable by anyone to handle direct inbound transfers.
Similarly for SimpleERC20Escrow.sol: L49
xINV = _xINV; // TODO: Test whether an immutable variable will persist across proxies
NatSpec statements are entirely missing for all constructors
and the four functions
referenced below:
function DOMAIN_SEPARATOR() public view virtual returns (bytes32) { return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator(); }
Similary, Market.sol: L97-99
function computeDomainSeparator() internal view virtual returns (bytes32) { return keccak256( abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(bytes(name)), keccak256("1"), block.chainid, address(this) ) ); }
Similary, Market.sol: L101-112
The following functions
are missing @return
statements
/** @notice Internal function for creating an escrow for users to deposit collateral in. @dev Uses create2 and minimal proxies to create the escrow at a deterministic address @param user The address of the user to create an escrow for. */ function createEscrow(address user) internal returns (IEscrow instance) {
Missing: @return
Similarly for the following functions:
The following functions
are missing @param
statements
/** @notice Gets the price of a specific token in DOLA @param token The address of the token to get price of @return The price of the token in DOLA, adjusted for token and feed decimals */ function viewPrice(address token, uint collateralFactorBps) external view returns (uint) {
Missing: @param collateralFactorBps
Similarly for Oracle.sol: L107-112
require
revert stringA require
message should be included to enable users to understand the reason for failure.
Recommendation: Add a brief (<= 32 char) explanatory message to each of the requires
referenced below. Consider using Custom Error codes (which would save both deployment and runtime cost and therefore be cheaper than revert strings).
require(globalSupply <= supplyCeiling);
require(msg.sender == beneficiary);
Similarly for INVEscrow.sol: L91
indexed
fieldsEach event
referenced below should use three indexed
fields if there are at least three fields
event Transfer(address indexed from, address indexed to, uint256 amount); event Approval(address indexed owner, address indexed spender, uint256 amount);
event Withdraw(address indexed account, address indexed to, uint amount); event Repay(address indexed account, address indexed repayer, uint amount); event ForceReplenish(address indexed account, address indexed replenisher, uint deficit, uint replenishmentCost, uint replenisherReward); event Liquidate(address indexed account, address indexed liquidator, uint repaidDebt, uint liquidatorReward);
#0 - c4-judge
2022-11-08T00:33:49Z
0xean marked the issue as grade-b