Versus-X audit

CertiKRepository at commit f5045b9

CertiK reviewed Versus-X (Versus-X audit) on 29 Mar 2024: 11 findings, 4 critical; 10 marked fixed, 1 acknowledged.

4 critical findings, fixed
Open the reportOpen Versus-X’s security record

Report hosted on skynet.certik.com.

Trustblock does not review code.

Findings11

Statuses are the security firm’s own, from its report.

SeverityOpenAcknowledgedFixed
Critical004
High012
Medium000
Low004
Critical`approveFrom()` can be used to steal tokensFixed

The function `approveFrom()` is a public function without any access control. It can be called by anyone to manipulate allowance information between arbitrary token owners and spenders such that hackers can easily steal tokens from any token owner.

Critical`mintVersusxToUser()` does not have access controFixed

The public function `mintVersusxToUser()` does not have any access control such that anyone can call it to mint arbitrary amount of tokens to any address. And it does not update total supply after minting, which may cause other critical bugs.

CriticalCentralization Related RisksFixed

In the contract **VERSUSX**, the role **MetaKeepLambdaOwner** has authority over the following functions: - setEskillzBet() In the contract **VERSUSX**, the role **Owner** has authority over the following functions: - mintMore() In the contract **VERSUSX**, the address **ESkillzBet** has authority over the following functions: - mintMore() Any compromise to the **MetaKeepLambdaOwner/Owner/ESkillzBet** account may allow a hacker to take advantage of this authority and mint an arbitrary amount of tokens to any address.

CriticalLow level call payload is not properly encoded anFixed

The payload of low level call should be constructed using one of `abi.encodeWithSelector()`, `abi.encodeWithSignature()`, `abi.encodeCall()`. If the first parameter is function signature string, then `abi.encodeWithSignature()` must be used. `abi.encodePacked()` only concatenates parameters tightly; it does not translate function signature to function selector and does not have proper padding for `userAddress` which is required for low level call payload. Even if an user provides correct function signature and user address, the identified low level call will always fail. And even worse, the function signature is not restricted and can point to any function, a hacker can construct a malicious function signature which points to functions like `approveMax()` to possibly steal tokens from the contract.

High`mintMore()` does not update total supply of tokeFixed

When tokens are minted, `_totalSupply` must be updated to reflect the total amount of existing tokens. Otherwise there will be inconsistency between the sum of token balances from all owners and `_totalSupply`, which may cause critical bugs.

HighPotential Lack of Access ControlFixed

The following three functions can be invoked to call the "CreateSPGame/CreateMP/JoinMPGame" function in the "ESkillzBet" contract. The implementation of these functions is unknown; however, based on the function names, they might not be functions that should be accessible to everyone: * approveAndCreateSPGame * approveAndCreateMPGame * approveAndJoinMPGame

LowNative tokens may be locked and lost in the contrFixed

In the contract `VERSUSX`, there are payable `receive()` and `executeMetaKeepLambdaTransaction()` functions which can receive native tokens; but there is no way to transfer native tokens out of the contract. Thus all the received native tokens will be locked and lost in the contract.

LowNon-standard EIP712 implementationFixed

The identified EIP712 implementation in the code is not standard compliant: it is clearly different from OpenZeppelin EIP712 implementation. It may lead to major compatibility issue.

LowOut-of-Scope DependenciesFixed

The contract declares and interacts with the out-of-scope contract `ESkillzBet`. The scope of the audit treats out-of-scope contracts as black boxes and assumes their functional correctness. However, in the real world, out-of-scope contracts can be compromised and this may lead to lost or stolen assets.

LowWhy Does the Contract Need to Inherit "MetaKeepLaFixed

Why does the VERSUSX contract need to inherit the "MetaKeepLambda" contract? It appears that the only feature utilized is the access control (e.g., onlyMetaKeepLambdaOwner), which could be achieved with the `Ownable` or `AccessControl` modules from the OpenZeppelin library. The auditor would like to know why the inheritance of "MetaKeepLambda" is deemed necessary.

Contracts in scope

No deployed address is recorded for this audit.

The report names a repository or files. Open the report to see its scope.

Repository and files the report names (1)

  • https://github.com/eSkillzGames/nft-marketplace/frontend(contract)/contracts/versusx.sol at commit f5045b98782e60d42dfb5aa3de6731b8e86dc5ab

Part of Versus-X’s security record

Versus-X
Audits1 audit by 1 firmLast audit Mar 2024, by CertiK.
Critical findingsNo open critical findingsIn that report, 4 critical findings were reported. Each is marked fixed by the firm that reported it.
Open Versus-X’s security record

Security firm

CertiK

1,044 projects reviewed · 1,375 reports · latest May 2025

See CertiK’s audits

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