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
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
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
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) {
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) {
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) {
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
16: ISwapRouter public constant swapRouter =
Version [5]
https://github.com/Cyfrin/2023-07-beedle/blob/main/src/Staking.sol
2: pragma solidity ^0.8.19;
https://github.com/Cyfrin/2023-07-beedle/blob/main/src/Lender.sol
2: pragma solidity ^0.8.19;
https://github.com/Cyfrin/2023-07-beedle/blob/main/src/Fees.sol
2: pragma solidity ^0.8.19;
https://github.com/Cyfrin/2023-07-beedle/blob/main/src/Beedle.sol
2: pragma solidity ^0.8.19;
https://github.com/Cyfrin/2023-07-beedle/blob/main/src/utils/Structs.sol
2: pragma solidity ^0.8.19;
https://github.com/Cyfrin/2023-07-beedle/blob/main/src/utils/Ownable.sol
2: pragma solidity ^0.8.19;
https://github.com/Cyfrin/2023-07-beedle/blob/main/src/utils/Errors.sol
2: pragma solidity ^0.8.19;
https://github.com/Cyfrin/2023-07-beedle/blob/main/src/interfaces/ISwapRouter.sol
https://github.com/Cyfrin/2023-07-beedle/blob/main/src/interfaces/IERC20.sol
2: pragma solidity ^0.8.19;
Initialized variables [6]
https://github.com/Cyfrin/2023-07-beedle/blob/main/src/Staking.sol
14: uint256 public balance = 0;
16: uint256 public index = 0;