Part of CertiK’s retainer series
CertiK reviewed WEMIX (Wemix Retainer 150 WEMEME) on 13 Feb 2025: 13 findings, 0 critical; 7 marked fixed, 6 open.
Report hosted on skynet.certik.com.
Trustblock does not review code.
Statuses are the security firm’s own, from its report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 0 |
| High | 1 | 0 | 1 |
| Medium | 1 | 0 | 0 |
| Low | 4 | 0 | 6 |
In the contract `WEMEMEBase`, the role `Setter` has authority over the functions shown in the diagram below. Any compromise to the `Setter` account may allow the hacker to take advantage of this authority and set the policy address.  In the contract `WEMEMERole`, the role `Setter` has authority over the functions shown in the diagram below. Any compromise to the `Setter` account may allow the hacker to take advantage of this authority and set the role manager.  In the contract `WEMEMEFactory`, the role `Setter` has authority over the functions shown in the diagram below. Any compromise to the `Setter` account may allow the hacker to take advantage of this authority and set the contract register.  In the contract `WEMEMEPolicy`, the role `Owner` has authority over the function `registToken()`, and the role `Setter` has authority over the functions shown in the diagram below. Any compromise to the `Setter` account may allow the hacker to take advantage of this authority and set the router address, set the listing fee, set the wwemix address, set the creator incentive fee, set the fee basis point, set the holder threshold, set the WemixD address, set the play swap router, set the wemixThreshold value, remove a specified token, set the factory address, set the fee recipient address, set the creation fee, and set the holder condition.  Note that the `Owner` also has the `Setter` role in the contracts above.
The `feeBasisPoint` can be set to approach 1 ether, which represents close to 100% fee ratio. When users sell `WEMEME` token via the bonding curve, the fee is deducted from the amount that users receive, which means that users could potentially receive minimal proceeds from the sale of tokens via the bonding curve.
When a new MEME token is created, the token creator can designate any `_virtualTokenReserves` and `_virtualWemixReserves` as long as they satisfy the requirements in line 26 and 27 of the `BondingCurve` contract. Given that the `_realTokenReserves` and `_realWemixReserves` are `TOTAL_SUPPLY` and `0` respectively, the token creator can choose a very small `_virtualWemixReserves` such as 1 wei. The advantage of setting a very low `_virtualWemixReserves` is that the first time buyer could use a very small amount of WEMIX to purchase a very large portion of the new MEME token, and subsequent buyers would have to pay a much higher price. Based on the following formula in the `getBuyPrice()` function, assume that `curve.virtualWemixReserves` and `curve.virtualTokenReserves` are `1` and `1e18` initially, and a buyer uses 1 Wemix to purchase the token. ```solidity uint256 n = curve.virtualWemixReserves * curve.virtualTokenReserves; uint256 i = curve.virtualWemixReserves + amount; uint256 r = (n / i) + 1; uint256 tokensToBuy = curve.virtualTokenReserves - r; ``` `n` would be `1e18`, `i` would be `2`, `r` would be `5e17 + 1`, and `tokensToBuy` would be `5e17 - 1`, which is almost half of the total supply of MEME token. If a subsequent buyer uses 1 Wemix to purchase the token, the amount purchased would be meaningfully less than half of the total supply given the shape of the bonding curve. This design could potentially allow token creators and snipers to gobble up a large percentage of new MEME token supply at the expense of future buyers. While the market mechanism would determine if future buyers choose to make subsequent token purchases, participants should be made aware of the implication of such a design.
The `WEMEMEFactory` contract interacts with out-of-scope dependencies, such as `contractRegistry`, `contractRegister`, and `playSwapRouter` contracts. The scope of the audit treats out-of-scope dependencies as black boxes and assumes their functional correctness, such as ensuring that the same `cName32` cannot be registered more than once.
The `_complete()` function contains a strict equality check that `c.realWemixReserves == wemixThreshold`. When users buy the tokens via the `buy()` function, line 158 `require(toUser >= minTokensOut, "Insufficient tokens out");` effectively put a minimum `amount` that a user can buy, and this value is added to `c.realWemixReserves` in line 170. This could potentially be problematic. For example, if the minimum amount that a user can buy is 10, but `c.realWemixReserves` is currently `wemixThreshold - 5`, then any buy transaction would fail and the `_complete()` function would never execute successfully.
In order to create a new pump token, the intended workflow is that a user calls the `create()` function of the `WEMEMErouter` contract, which in turn calls the `create()` function of the `WEMEMEFactory` contract to deploy a new `WEMEME` token. However, anyone can also deploy a `WEMEME` token directly without going through `WEMEMERouter` and `WEMEMEFactory` and set its own `_roleManager` and `_policy` addresses that are different from those set by the project team. While these tokens will not be registered in the official `contractRegistry`, it can potentially be confusing to normal users.
The report names a repository or files. Open the report to see its scope.
Repository and files the report names (12)
1,044 projects reviewed · 1,375 reports · latest May 2025
See CertiK’s auditsSomething 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