Venturus logo

Eagle Audit Logo

Eagle Audit is an integrated development environment focused on smart contract security, allowing users to import, edit and analyze smart contract code. Compile projects, run static analyzers, unit tests, generate reports and chat with our AI to secure your code.

AI analysis

Use our language model trained specifically on smart contracts to quickly get an overview of any project, clarify code snippets, identify bugs, and even generate unit tests.

AI Copilot

Write code faster with our AI assistant.

Get code from any blockchain or Github

Import, edit and analyze contracts from Github or directly from Ethereum and its L2s.

Static Analysis

Identify bugs, mistakes or dangerous patterns in contract code with several static analysis tools.

4 issues detected.
High: 2
Medium: 1
Optimization: 1
Detection: Reentrancy
High
Detection: Arbitrary Call
High
Detection: Locked Ether
Medium
Detection: Modify storage in loop
Optimization

Unit Tests

Write and run Foundry unit tests to verify the behavior of a contract.

Function: testFuzz_setNumber(uint256)
SuccessFuzz Test
Function: testWethFlashLoan()
SuccessStandard Test
Foundry tests

Graphs

Verify all function calls in a smart contracts with a graph view.

Graph example

Automated Reports

Use the automated report tool to quickly summarize the issues of a project into a neatly formatted Markdown report.

Analysis Report

Table of Contents

Summary

Files Summary

KeyValue
.sol Files1
Total nSLOC710

Files Details

FilepathnSLOC
src/Contract.sol710
Total710

Issue Summary

CategoryNo. of Issues
High2
Low8

High Issues

H-1: abi.encodePacked() should not be used with dynamic types when passing the result to a hash function such as keccak256()

Use abi.encode() instead which will pad items to 32 bytes, which will prevent hash collisions (e.g. abi.encodePacked(0x123,0x456) => 0x123456 => abi.encodePacked(0x1,0x23456), but abi.encode(0x123,0x456) => 0x0...1230...456). Unless there is a compelling reason, abi.encode should be preferred. If there is only one argument to abi.encodePacked() it can often be cast to bytes() or bytes32() instead. If all arguments are strings and or bytes, bytes.concat() should be used instead.

  • Found in src/Contract.sol Line: 290

            pair = address(uint(keccak256(abi.encodePacked(

H-2: Unprotected initializer

Consider protecting the initializer functions with modifiers.

  • Found in src/Contract.sol Line: 193

        function INIT_CODE_PAIR_HASH() external view returns (bytes32);
  • Found in src/Contract.sol Line: 268

        function initialize(address, address) external;

Low Issues

L-1: Unsafe ERC20 Operations should not be used

ERC20 functions may not behave as expected. For example: return values are not always meaningful. It is recommended to use OpenZeppelin's SafeERC20 library.

  • Found in src/Contract.sol Line: 479

            assert(IWETH(WETH).transfer(pair, amountETH));
  • Found in src/Contract.sol Line: 496

            IPancakePair(pair).transferFrom(msg.sender, pair, liquidity); // send liquidity to pair
  • Found in src/Contract.sol Line: 647

            assert(IWETH(WETH).transfer(PancakeLibrary.pairFor(factory, path[0], path[1]), amounts[0]));
  • Found in src/Contract.sol Line: 696

            assert(IWETH(WETH).transfer(PancakeLibrary.pairFor(factory, path[0], path[1]), amounts[0]));
  • Found in src/Contract.sol Line: 754

            assert(IWETH(WETH).transfer(PancakeLibrary.pairFor(factory, path[0], path[1]), amountIn));

L-2: Solidity pragma should be specific, not wide

Consider using a specific version of Solidity in your contracts instead of a wide version. For example, instead of pragma solidity ^0.8.0;, use pragma solidity 0.8.0;

  • Found in src/Contract.sol Line: 3

    pragma solidity >=0.6.0;
  • Found in src/Contract.sol Line: 33

    pragma solidity >=0.6.2;
  • Found in src/Contract.sol Line: 131

    pragma solidity >=0.6.2;
  • Found in src/Contract.sol Line: 176

    pragma solidity >=0.5.0;
  • Found in src/Contract.sol Line: 218

    pragma solidity >=0.5.0;
  • Found in src/Contract.sol Line: 273

    pragma solidity >=0.5.0;
  • Found in src/Contract.sol Line: 357

    pragma solidity >=0.5.0;
  • Found in src/Contract.sol Line: 377

    pragma solidity >=0.5.0;

L-3: public functions not used internally could be marked external

Instead of marking a function as public, consider marking it as external if it is not used internally.

  • Found in src/Contract.sol Line: 786

        function quote(uint amountA, uint reserveA, uint reserveB) public pure virtual override returns (uint amountB) 
  • Found in src/Contract.sol Line: 790

        function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut)
  • Found in src/Contract.sol Line: 800

        function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut)
  • Found in src/Contract.sol Line: 810

        function getAmountsOut(uint amountIn, address[] memory path)
  • Found in src/Contract.sol Line: 820

        function getAmountsIn(uint amountOut, address[] memory path)

L-4: Define and use constant variables instead of using literals

If the same constant literal value is used multiple times, create a constant state variable and reference it throughout the contract.

  • Found in src/Contract.sol Line: 317

            uint amountInWithFee = amountIn.mul(9975);
  • Found in src/Contract.sol Line: 319

            uint denominator = reserveIn.mul(10000).add(amountInWithFee);
  • Found in src/Contract.sol Line: 327

            uint numerator = reserveIn.mul(amountOut).mul(10000);
  • Found in src/Contract.sol Line: 328

            uint denominator = reserveOut.sub(amountOut).mul(9975);

L-5: Event is missing indexed fields

Index event fields make the field more quickly accessible to off-chain tools that parse events. However, note that each index field costs extra gas during emission, so it's not necessarily best to index the maximum allowed per event (three fields). Each event should use three indexed fields if there are three or more fields, and gas usage is not particularly of concern for the events in question. If there are fewer than three fields, all of the fields should be indexed.

  • Found in src/Contract.sol Line: 179

        event PairCreated(address indexed token0, address indexed token1, address pair, uint);
  • Found in src/Contract.sol Line: 221

        event Approval(address indexed owner, address indexed spender, uint value);
  • Found in src/Contract.sol Line: 222

        event Transfer(address indexed from, address indexed to, uint value);
  • Found in src/Contract.sol Line: 241

        event Mint(address indexed sender, uint amount0, uint amount1);
  • Found in src/Contract.sol Line: 242

        event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
  • Found in src/Contract.sol Line: 243

        event Swap(
  • Found in src/Contract.sol Line: 251

        event Sync(uint112 reserve0, uint112 reserve1);
  • Found in src/Contract.sol Line: 360

        event Approval(address indexed owner, address indexed spender, uint value);
  • Found in src/Contract.sol Line: 361

        event Transfer(address indexed from, address indexed to, uint value);

L-6: PUSH0 is not supported by all chains

Solc compiler version 0.8.20 switches the default target EVM version to Shanghai, which means that the generated bytecode will include PUSH0 opcodes. Be sure to select the appropriate EVM version in case you intend to deploy on a chain other than mainnet like L2 chains that may not support PUSH0, otherwise deployment of your contracts will fail.

  • Found in src/Contract.sol Line: 3

    pragma solidity >=0.6.0;
  • Found in src/Contract.sol Line: 33

    pragma solidity >=0.6.2;
  • Found in src/Contract.sol Line: 131

    pragma solidity >=0.6.2;
  • Found in src/Contract.sol Line: 176

    pragma solidity >=0.5.0;
  • Found in src/Contract.sol Line: 218

    pragma solidity >=0.5.0;
  • Found in src/Contract.sol Line: 273

    pragma solidity >=0.5.0;
  • Found in src/Contract.sol Line: 357

    pragma solidity >=0.5.0;
  • Found in src/Contract.sol Line: 377

    pragma solidity >=0.5.0;

L-7: Large literal values multiples of 10000 can be replaced with scientific notation

Use e notation, for example: 1e18, instead of its full numeric value.

  • Found in src/Contract.sol Line: 319

            uint denominator = reserveIn.mul(10000).add(amountInWithFee);
  • Found in src/Contract.sol Line: 327

            uint numerator = reserveIn.mul(amountOut).mul(10000);

L-8: Internal functions called only once can be inlined

Instead of separating the logic into a separate function, consider inlining the logic into the calling function. This can reduce the number of function calls and improve readability.

  • Found in src/Contract.sol Line: 314

        function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) internal pure returns (uint amountOut) 
  • Found in src/Contract.sol Line: 324

        function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) internal pure returns (uint amountIn) 

This report was generated by Aderyn, a static analysis tool built by Cyfrin, a blockchain security company.