As of 30 Oct 2026, Wido has 2 audit reports by 2 security firms on Trustblock; the latest is by OpenZeppelin, dated 25 Oct 2023. Those reports list no open critical findings.
Record last updated . It holds audits and findings, contracts and incidents up to Oct 2026. Trustblock does not review code.
Newest first
| Audit | Security firm | Date | Scope | Critical findings | Report |
|---|---|---|---|---|---|
| Wido Comet Collateral Swap Contracts | Security firm: OpenZeppelin | Date: | Scope: Files named in the report | 2 critical findings, fixed | Open · blog.openzeppelin.com |
| Wido - Audit | Security firm: CertiK | Date: | Scope: Files named in the report | No open critical findings | Open · skynet.certik.com |
Statuses are the security firm’s own, from each report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 2 |
| High | 1 | 0 | 0 |
| Medium | 1 | 1 | 1 |
| Low | 1 | 1 | 5 |
The report gives no description here.
Open the reportThe report gives no description here.
Open the reportIn the contract `WidoRouter`, function `executeOrder()` takes `feeBps` as input, which specifies how many fees to be charged. ```solidity=279 function executeOrder( Order calldata order, Step[] calldata route, uint256 feeBps, address partner ) ``` Later, the variable `feeBps` will be passed to the function `_collectFees()` to calculate the `fee` that will be transferred to the `bank` address. ```solidity function _collectFees(address fromToken, uint256 amount, uint256 feeBps) private { require(feeBps <= 100, "Fee out of range"); uint256 fee = (amount * feeBps) / 10000; if (fromToken == address(0)) { bank.safeTransferETH(fee); } else { ERC20(fromToken).safeTransfer(bank, fee); } } ``` However, there is no restriction for the input `feeBps` in the linked functions. Consequently, users can set the input `feeBps` to zero and thus bypassing the `require()` statement.
Open the reportThe report gives no description here.
Open the reportIn the function `executeOrderWithSignature()`, users can sign and delegate the transaction to another party. ```solidity=316 function executeOrderWithSignature( Order calldata order, Step[] calldata route, uint8 v, bytes32 r, bytes32 s, uint256 feeBps, address partner ) external override nonReentrant { require(verifyOrder(order, v, r, s), "Invalid order"); nonces[order.user]++; _executeOrder(order, route, order.user, feeBps); emit FulfilledOrder(order, msg.sender, order.user, feeBps, partner); } ``` However, the contract only verifies the `Order` struct signed by the users and does not validate input `route`. In this case, the attacker can spoof a malicious `route` payload, which calls a malicious contract. Therefore, users might suffer unexpected loss. Due to the protection on `minOutputAmount`, which enforces the minimum output amount from the swap, otherwise, it will revert. ```solidity if (toTokenBalance < order.minOutputAmount) revert SlippageTooHigh(order.minOutputAmount, toTokenBalance); ``` However, users might mistakenly set the `minOutputAmount,` thus creating a chance for attackers to steal their funds.
Open the reportThe Wido project allows user to call arbitrary addresses to swap their tokens, which is specified in the `route` calldata. ```solidity function _executeSteps(Step[] calldata route) private { ``` The concern is that if a vulnerable swap contract is used during the call (i.e., in `route` input), it could lead to users' asset loss. For example, a user wants to swap tokens in a certain `route`, however, one of the swap contract in the `route` is vulnerable and drains 10% of the amount from user's input amount. Therefore, after swapping, the user to will lose 10% of the tokens during this swap.
Open the reportIn the `WidoRouter` contract, the low-level call is implemented to perform swap operation in a flexible way. ```solidity=129 (bool success, bytes memory result) = step.targetAddress.call{value: value}(editedSwapData); ``` As per the current design, users will approve funds to the WidoManager contract instead of the `WidoRouter` contract, which will prevent attackers from directly triggering the low-level call with `transferFrom()` invocation to drain users' assets. Users should never approve the WidoRouter contract. If users approve `WidoRouter` contract by mistake, it could lead to a potential loss of funds.
Open the reportIn the `WidoRouter` contract, users can swap tokens via the `executeOrder()` function call with a designated input `Order` struct. ```solidity function executeOrder( Order calldata order, Step[] calldata route, uint256 feeBps, address partner ) ``` ```solidity struct Order { OrderInput[] inputs; OrderOutput[] outputs; address user; uint32 nonce; uint32 expiration; } ``` The `order.inputs` specifies the amount of `from` tokens to be swapped. The exact amount (`order.inputs`) tokens will be pulled from user's address during the `_executeOrder()` operation. After the swap, all the `toTokens` in the contract will be transferred to user's address. However, due to the various swapping mechanisms of different protocols, there might be some potential `fromToken` leftovers in the `WidoRouter` contract during the swap. For example, a user wants to swap 100 tokens. The exact 100 tokens will be pulled from the user's address to the `WidoRouter` contract. If the external swap protocol only takes 98 tokens for swapping, there will be two tokens left in the `WidoRouter`. Consequently, other users could exploit the low-level call to transfer the leftovers to their own addresses. It is also worth mentioning that if the swapping is performed via multiple paths, there could be multiple token leftovers inside 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="wido"></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