20,000 USDC
View results
Submission Details
Severity: gas
Valid

QA


Layout Order [1]

  • The best-practices for layout within a contract is the following order: state variables, events, modifiers, constructor and functions.

https://github.com/Cyfrin/2023-07-beedle/blob/main/src/Lender.sol

// place these events after all the state variables
11: event PoolCreated(bytes32 indexed poolId, Pool pool);
12: event PoolUpdated(bytes32 indexed poolId, Pool pool);
13: event PoolBalanceUpdated(bytes32 indexed poolId, uint256 newBalance);
14: event PoolInterestRateUpdated(
18: event PoolMaxLoanRatioUpdated(
22: event Borrowed(
31: event Repaid(
40: event AuctionStart(
49: event LoanBought(uint256 loanId);
50: event LoanSiezed(
56: event Refinanced(uint256 loanId);

Function Visibility [2]

  • Order of Functions: Ordering helps readers identify which functions they can call and to find the constructor and fallback definitions easier. Functions should be grouped according to their visibility and ordered: constructor, receive function (if exists), fallback function (if exists), external, public, internal, private. Within a grouping, place the view and pure functions last.

https://github.com/Cyfrin/2023-07-beedle/blob/main/src/Lender.sol

// public functions coming before some external ones, should come after
108: function getPoolId(
130: function setPool(Pool calldata p) public returns (bytes32 poolId) {
232: function borrow(Borrow[] calldata borrows) public {
292: function repay(uint256[] calldata loanIds) public {
437: function startAuction(uint256[] calldata loanIds) public {
465: function buyLoan(uint256 loanId, bytes32 poolId) public {

https://github.com/Cyfrin/2023-07-beedle/blob/main/src/Beedle.sol

// place this external function before all the internal ones.
36: function mint(address to, uint256 amount) external onlyOwner {

natSpec missing [3]

Some functions are missing @params or @returns. Specification Format.” These are written with a triple slash (///) or a double asterisk block(/** ... */) directly above function declarations or statements to generate documentation in JSON format for developers and end-users. It is recommended that Solidity contracts are fully annotated using NatSpec for all public interfaces (everything in the ABI). These comments contain different types of tags:

  • @title: A title that should describe the contract/interface @author: The name of the author (for contract, interface)

  • @notice: Explain to an end user what this does (for contract, interface, function, public state variable, event)

  • @dev: Explain to a developer any extra details (for contract, interface, function, state variable, event)

  • @param: Documents a parameter (just like in doxygen) and must be followed by parameter name (for function, event)

  • @return: Documents the return variables of a contract’s function (function, public state variable)

  • @inheritdoc: Copies all missing tags from the base function and must be followed by the contract name (for function, public state variable)

  • @custom…: Custom tag, semantics is application-defined (for everywhere)

https://github.com/Cyfrin/2023-07-beedle/blob/main/src/Staking.sol

7: interface FeeDistribution {
8: function claim(address) external;
11: contract Staking is Ownable {
31: constructor(address _token, address _weth) Ownable(msg.sender) {
// @dev or @notice missing
38: function deposit(uint _amount) external {
46: function withdraw(uint _amount) external {

https://github.com/Cyfrin/2023-07-beedle/blob/main/src/Lender.sol

10: contract Lender is Ownable {
11: event PoolCreated(bytes32 indexed poolId, Pool pool);
12: event PoolUpdated(bytes32 indexed poolId, Pool pool);
13: event PoolBalanceUpdated(bytes32 indexed poolId, uint256 newBalance);
14: event PoolInterestRateUpdated(
18: event PoolMaxLoanRatioUpdated(
22: event Borrowed(
31: event Repaid(
40: event AuctionStart(
49: event LoanBought(uint256 loanId);
50: event LoanSiezed(
56: event Refinanced(uint256 loanId);
73: constructor() Ownable(msg.sender) {
// @dev or @notice missing
84: function setLenderFee(uint256 _fee) external onlyOwner {
92: function setBorrowerFee(uint256 _fee) external onlyOwner {
100: function setFeeReceiver(address _feeReceiver) external onlyOwner {
108: function getPoolId(
116: function getLoanDebt(uint256 loanId) external view returns (uint256 debt) {
// @return missing
130: function setPool(Pool calldata p) public returns (bytes32 poolId) {

https://github.com/Cyfrin/2023-07-beedle/blob/main/src/Fees.sol

11: contract Fees {
19: constructor(address _weth, address _staking) {

https://github.com/Cyfrin/2023-07-beedle/blob/main/src/Beedle.sol

9: contract Beedle is Ownable, ERC20, ERC20Permit, ERC20Votes {
11: constructor() ERC20("Beedle", "BDL") ERC20Permit("Beedle") Ownable(msg.sender) {
15: function _afterTokenTransfer(address from, address to, uint256 amount)
22: function _mint(address to, uint256 amount)
29: function _burn(address account, uint256 amount)
36: function mint(address to, uint256 amount) external onlyOwner {

https://github.com/Cyfrin/2023-07-beedle/blob/main/src/utils/Ownable.sol

4: abstract contract Ownable {
6: event OwnershipTransferred(address indexed user, address indexed newOwner);
10: modifier onlyOwner() virtual {
14: constructor(address _owner) {
19: function transferOwnership(address _owner) public virtual onlyOwner {

https://github.com/Cyfrin/2023-07-beedle/blob/main/src/interfaces/ISwapRouter.sol

4: ISwapRouter
5: struct ExactInputSingleParams {
16: function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut);

https://github.com/Cyfrin/2023-07-beedle/blob/main/src/utils/Errors.sol

2: pragma solidity ^0.8.19;
4: error PoolConfig();
5: error LoanTooSmall();
6: error LoanTooLarge();
7: error RatioTooHigh();
8: error FeeTooHigh();
9: error TokenMismatch();
10: error Unauthorized();
11: error AuctionStarted();
12: error AuctionNotStarted();
13: error AuctionEnded();
14: error AuctionNotEnded();
15: error RateTooHigh();
16: error PoolTooSmall();
17: error ZeroCollateral();
18: error AuctionTooShort();

https://github.com/Cyfrin/2023-07-beedle/blob/main/src/interfaces/IERC20.sol

4: interface IERC20 {
5: event Transfer(address indexed from, address indexed to, uint256 value);
6: event Approval(address indexed owner, address indexed spender, uint256 value);
7: function totalSupply() external view returns (uint256);
8: function balanceOf(address account) external view returns (uint256);
9: function transfer(address to, uint256 amount) external returns (bool);
10: function allowance(address owner, address spender) external view returns (uint256);
11: function approve(address spender, uint256 amount) external returns (bool);
12: function transferFrom(address from, address to, uint256 amount) external returns (bool);

State variable and function names [4]

  • Variables should be named according to their specifications

  • private and internal variables should preppend with underline

  • private and internal functions should preppend with underline

  • constant state variables should be UPPER_CASE

https://github.com/Cyfrin/2023-07-beedle/blob/main/src/Fees.sol

// constant state variables should be UPPER_CASE
16: ISwapRouter public constant swapRouter =

Version [5]

  • Pragma versions should be standardized and avoid floating pragma ( ^ ).

https://github.com/Cyfrin/2023-07-beedle/blob/main/src/Staking.sol

// lock the this for a safer version by removing the ^
2: pragma solidity ^0.8.19;

https://github.com/Cyfrin/2023-07-beedle/blob/main/src/Lender.sol

// lock the this for a safer version by removing the ^
2: pragma solidity ^0.8.19;

https://github.com/Cyfrin/2023-07-beedle/blob/main/src/Fees.sol

// lock the this for a safer version by removing the ^
2: pragma solidity ^0.8.19;

https://github.com/Cyfrin/2023-07-beedle/blob/main/src/Beedle.sol

// lock the this for a safer version by removing the ^
2: pragma solidity ^0.8.19;

https://github.com/Cyfrin/2023-07-beedle/blob/main/src/utils/Structs.sol

// lock the this for a safer version by removing the ^
2: pragma solidity ^0.8.19;

https://github.com/Cyfrin/2023-07-beedle/blob/main/src/utils/Ownable.sol

// lock the this for a safer version by removing the ^
2: pragma solidity ^0.8.19;

https://github.com/Cyfrin/2023-07-beedle/blob/main/src/utils/Errors.sol

// lock the this for a safer version by removing the ^
2: pragma solidity ^0.8.19;

https://github.com/Cyfrin/2023-07-beedle/blob/main/src/interfaces/ISwapRouter.sol

// lock the this for a safer version by removing the ^
pragma solidity ^0.8.19;

https://github.com/Cyfrin/2023-07-beedle/blob/main/src/interfaces/IERC20.sol

// lock the this for a safer version by removing the ^
2: pragma solidity ^0.8.19;

Initialized variables [6]

  • Variables are default initialized with 0 for uint / int, 0x0 for address and false for bool

https://github.com/Cyfrin/2023-07-beedle/blob/main/src/Staking.sol

// values initialized with its default value.
14: uint256 public balance = 0;
16: uint256 public index = 0;

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!