As of 3 Nov 2026, Indorse 2.0 Ecosystem has 1 audit report on Trustblock, by QuillAudits, dated 1 Sep 2023. That report lists no open critical findings.
Record last updated . It holds audits, findings and contracts up to Nov 2026, and incidents up to Oct 2026. Trustblock does not review code.
Newest first
| Audit | Security firm | Date | Scope | Critical findings | Report |
|---|---|---|---|---|---|
| Indorse | Security firm: QuillAudits | Date: | Scope: Files named in the report | No open critical findings | Open · quillaudits.com |
Statuses are the security firm’s own, from each report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 0 |
| High | 1 | 0 | 0 |
| Medium | 0 | 0 | 0 |
| Low | 7 | 0 | 10 |
The check (msg.sender == entrypoint) is used multiple times and can be converted into a modifier.
Open the reportA number of externally facing functions in the codebase are declared public but are not called internally or cross-contract. If there is no chance to reuse these functions in an internal contract call (because external functions cannot be called within the same contract), as external functions are cheaper than public functions it would be beneficial to adjust the function visibility. In KillSwitchValidator.sol, ECDSAValidator.sol, ERC165SessionKeyValidator, MultiECDSAValidator, SessionKeyOwnedValidator, the functions (i) getAccountAddress() and (ii) validateSignature() can be declared external instead of public.
Open the reportIn Kernel, it is expected that the execute() function is called with the target contract `to` being an external contract. The risk here is that an EOA can be delegatecalled or called and returns true as though it were a successful contract call. The execution fails to happen and there would be no reverts to show why.
Open the reportThere is no validation of the `to` addresses in the executeBatch() as well as the `tokenAddress` array of approveAndTransfer20Batch() of BatchActions.sol. If there is no check, transfers can go to address(0), value and data could also be zero values.
Open the reportIn the validateUserOp function in Kernel.sol, there is a redundancy found in variable assignment and declaration. It is unnecessary to initialize variables to the default value (e.g. uint256 i = 0), or to reassign the same variable to itself (unchanged) in the same function execution.In the Kernel.sol file, `op` is assigned the same value twice.
Open the reportThere is a slight discrepancy between the OpenZeppelin implementation and the EIP1967Proxy implementation, as msg.value is not checked. The check for msg.value is because when the data length passed is 0, it does not initiate the delegatecall to the logic contract and the value passed can get stuck in the contract.
Open the reportThe MultiECDSAKernelFactory utilizes the onlyOwner modifier inherited from the Ownable library. Functions in this contract with this modifier adjust key parameters in the entrypoint’s stake and the owners array. If the owner (from onlyOwner) is compromised, stake can be unlocked and withdrawn, or malicious users can be added to the `owners` array.
Open the reportThe Kernel smart wallets are expected to be deployed on multiple EVM-based chains, some of which are Optimism, Arbitrum, Scroll, Linea, Polygon and Base) however solidity pramga versions above 0.8.19 may prove incompatible on chains like Arbitrum which do not support the PUSH0 opcode. To ensure the same deterministic bytecode is available across all chains, consider locking the pragma versions to 0.8.19.
Open the reportThe logic address passed in to the EIP1967 proxy is used to deploy new kernel accounts. Although this happens only once, when the proxy is deployed there is no check for address validity. An EOA can be passed into the constructor which will pass the delegatecall without reverting.
Open the reportIKernel is an empty interface declared and not used within the contract.
Open the reportThe reports name a repository or files. Open a report to see its scope.
Is this your project? Show this record on your own website. The label states what the record holds, links to this page and updates by itself. It is free and needs no sign-in.
Automatic: the three strongest facts of this project’s own record (its last audit and two more), highlighted. They update with the record. Picking a fact turns Automatic off.
<head><script src="https://widget.trustblock.run/project-widget.min.js" defer></script></head><body><divdata-tb-project-widgetdata-tb-project-slug="indorse"></div></body>
Paste the code where the label should appear. It uses no API credit and updates by itself.
Something wrong on this page? A missing report, a wrong date, a finding that was fixed since. Tell us and we check it against its source.
Tell us