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.
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.
Write code faster with our AI assistant.
Import, edit and analyze contracts from Github or directly from Ethereum and its L2s.
Identify bugs, mistakes or dangerous patterns in contract code with several static analysis tools.
Write and run Foundry unit tests to verify the behavior of a contract.
Verify all function calls in a smart contracts with a graph view.
Use the automated report tool to quickly summarize the issues of a project into a neatly formatted Markdown report.
public
functions not used internally could be marked external
constant
variables instead of using literalsindexed
fieldsKey | Value |
---|---|
.sol Files | 1 |
Total nSLOC | 710 |
Filepath | nSLOC |
---|---|
src/Contract.sol | 710 |
Total | 710 |
Category | No. of Issues |
---|---|
High | 2 |
Low | 8 |
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(
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;
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));
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;
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)
constant
variables instead of using literalsIf 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);
indexed
fieldsIndex 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);
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;
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);
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.