Vanilla security record

As of 3 Nov 2026, Vanilla has 1 audit report on Trustblock, by CertiK, dated 2 Aug 2023. That report lists no open critical findings.

Critical findings
No open critical findings
In 1 report.
Open the latest report
Your label, live
Get the label for your site

Record last updated . It holds audits, findings and contracts up to Nov 2026, and incidents up to Oct 2026. Trustblock does not review code.

Audits1

Newest first

AuditSecurity firmDateScopeCritical findingsReport
Vanilla ContractSecurity firm: CertiKDate: Scope: Files named in the reportNo open critical findingsOpen · skynet.certik.com

Findings22

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

SeverityOpenAcknowledgedFixed
Critical000
High010
Medium000
Low4017
Low`Distributor.rewardAmount()` uses `msg.sender` inVanilla Contract · CertiK · 2 Aug 2023Fixed

`rewardAmount()` is supposed to calculate the reward claimable by `account`. However, `msg.sender` is used as argument for `getBoostedAmount()`.

Open the report
Low`Locker.increaseLockPeriod()` allows increasing tVanilla Contract · CertiK · 2 Aug 2023Fixed

```sol=144 require(beforeUnlockBlock < afterUnlockBlock, "Vanilla: period"); ``` `increaseLockPeriod()` checks if block number is increasing, however, it's more reasonable to check if stage is.

Open the report
Low`Reinforcer.numWords` is redundantVanilla Contract · CertiK · 2 Aug 2023Fixed

`Reinforcer` always uses only one random word in `fulfillRandomWords()`. The `numWords` state field is redundant.

Open the report
Low`rewardPool` is supposed to be `depositToken`Vanilla Contract · CertiK · 2 Aug 2023Fixed

The argument `rewardPool` of `Distributor.NewRewardPool` event is in fact `depositToken`. The function `Distributor.rewardPerPeriod()` in fact returns `rewardSince`.

Open the report
Low`Ticket.pendingTokenIds` is not encapsulatedVanilla Contract · CertiK · 2 Aug 2023Fixed

`Vanilla721.mint()` directly checks if `!ticket.pendingTokenIds(tokenId)` and then does `ticket.setPendingTokenIds(tokenId)`. However, it is reasonable to perform this check directly in `Ticket.setPendingTokenIds()` to hide the implementation details.

Open the report
LowDivide Before MultiplyVanilla Contract · CertiK · 2 Aug 2023Fixed

Performing integer division before multiplication truncates the low bits, losing the precision of calculation. ```solidity=220 uint rewardPerPool = rewardPerPeriod(poolState.lastUpdatedBlock) * poolState.rewardWeight / totalRewardWeight; ``` ```solidity=224 poolState.rewardRate += safe144(rewardPerPool * 1e18 / poolState.totalDeposit); ``` --- ```solidity=53 newMaxRewardWeights[i] = safe112( maxNumber / subtractedPoint * reinforceVanillaFee ); ```

Open the report
LowInefficient `memory` ParameterVanilla Contract · CertiK · 2 Aug 2023Fixed

One or more parameters with `memory` data location are never modified in their functions and those functions are never called internally within the contract. Thus, their data location can be changed to `calldata` to avoid the gas consumption copying from calldata to memory. ```solidity=53 function submitTransaction( ``` `submitTransaction` has memory location parameters: `signature`, `data`.

Open the report
LowLack of sanity checkVanilla Contract · CertiK · 2 Aug 2023Fixed

`Distributor.constructor()` and `setTokenPerBlock()` don't check if `newStartBlock` and `newTokenPerBlock` are valid. `Locker.setBoostDivider()` doesn't check if `boostDivider` is non-zero.

Open the report
LowNo Upper Limits for FeesVanilla Contract · CertiK · 2 Aug 2023Fixed

There is no upper limit restricting parameter of `setFeePercentage()`, potentially enabling up to 100% of fees on transactions.

Open the report
LowPotential Reentrancy AttackVanilla Contract · CertiK · 2 Aug 2023Fixed

`Locker.increaseLockPeriod()` is not protected from reentrancy, however, does external calls and updates `accountState.rewardDebt` after that.

Open the report
Show 7 more
LowPull-Over-Push Pattern In `Vanilla.setAdmin()` FuVanilla Contract · CertiK · 2 Aug 2023Fixed

`Vanilla.setAdmin()` sets the new admin without guaranteeing they are able to actuate transactions on-chain.

Open the report
LowUnsafe Integer CastVanilla Contract · CertiK · 2 Aug 2023Fixed

Type casting refers to changing the variable of one data type into another. The code contains an unsafe cast between integer types, which may result in unexpected truncation or sign flipping of the value. ```solidity=100 uint32(startBlock > block.number ? startBlock : block.number), ``` `startBlock` is declared as `uint`. If it was initialized bigger than `type(uint32).max`, the result of `addRewardPool()` is unexpected. --- ```solidity=260 return blockNumber < startBlock ? uint16(passedStage) : uint16((blockNumber - startBlock) / blockPeriod + passedStage); ``` `blockNumber` is provided by the user as `uint`. The result of type truncation is unexpected. --- ```solidity=23 int i = int(to); ``` `BIT` uses unsafe type casting.

Open the report
LowUnused codeVanilla Contract · CertiK · 2 Aug 2023Fixed

`BIT.safe16()`, `Distributor.safe112()`, `Distributor.blocksPerYear` are never used.

Open the report
LowUnused eventVanilla Contract · CertiK · 2 Aug 2023Fixed

The event `Reinforcer.NewReinforceLinkFee` is never used.

Open the report
LowUsage of `transfer()` for Sending Native TokensVanilla Contract · CertiK · 2 Aug 2023Fixed

It is not recommended to use Solidity's `transfer()` and `send()` functions for transferring native tokens. Those functions forward only a fixed amount of gas (2300 specifically) and the receiving contracts may run out of gas before finishing the transfer. Also, EVM instructions' gas costs may increase in the future. Thus, some contracts that can receive now may stop working in the future due to the gas limitation. ```solidity=198 payable(msg.sender).transfer(amount); ``` - `Distributor.withdraw` uses `transfer()`.

Open the report
LowUsage of Magic NumbersVanilla Contract · CertiK · 2 Aug 2023Fixed

Different magic numbers are used as-is in code.

Open the report
LowVariables Can Be Declared as `immutable`Vanilla Contract · CertiK · 2 Aug 2023Fixed

The linked variables assigned in the constructor can be declared as `immutable`. Immutable state variables can be assigned during contract creation but will remain constant throughout the lifetime of a deployed contract. A big advantage of immutable variables is that reading them is significantly cheaper than reading from regular state variables since they will not be stored in storage.

Open the report

Contracts

No deployed address is recorded for these audits.

The reports name a repository or files. Open a report to see its scope.

The repositories and files the reports name

Show this on your site

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.

Content

Facts

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.

Fixed as
Language

Style

Layout
Theme
Accent
Corners

Format

Size
Date
Embed as
HTML
<head>
<script src="https://widget.trustblock.run/project-widget.min.js" defer></script>
</head>
<body>
<div
data-tb-project-widget
data-tb-project-slug="bum-1"
></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