CertiK reviewed Jager Hunter (Jager Hunter 2) on 28 Apr 2025: 7 findings, 0 critical; 4 marked fixed, 1 acknowledged, 2 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 | 0 | 0 | 1 |
| Medium | 0 | 1 | 1 |
| Low | 2 | 0 | 2 |
In the `JagerHunterLP` contract, the `poolInfo.lastRewardBlock` variable indicates the block number of the last reward update, which is essential for calculating rewards generated by the pool. This variable is updated whenever rewards are added or when the pool is updated. ```solidity function updatePool() public { if(rewardPerBlock == 0) return; @> if (poolInfo.totalAmount == 0) return; if (block.number <= poolInfo.lastRewardBlock) return; uint256 currentMaxBlockNumber = endBlock > block.number ? block.number : endBlock; if(currentMaxBlockNumber > poolInfo.lastRewardBlock) { uint256 jagerReward = (currentMaxBlockNumber - poolInfo.lastRewardBlock) * rewardPerBlock; poolInfo.releaseReward += jagerReward; poolInfo.accLPPerShare = poolInfo.accLPPerShare + (jagerReward * 1e12 / poolInfo.totalAmount); } else { rewardPerBlock = 0; } poolInfo.lastRewardBlock = block.number; } ``` However, in the `updatePool()` function, if there are no staked assets in the pool (`poolInfo.totalAmount == 0`), the function exits without updating `poolInfo.lastRewardBlock`. This issue causes reward calculations to disregard the initial staked block, resulting in users potentially receiving more rewards than they should when assets are eventually staked.
The `addReward()` function allows any account to deposit `jager` tokens into the `JagerHunterLP` reward pool. Upon deposit, the newly added rewards (combined with any remain rewards) will be redistributed across blocks generated during the next 7-day period. The reward distribution period is automatically reset to start at the current block and end after 7 days' worth of blocks. ```solidity function addReward(uint256 amount) external { if(amount == 0) return; TransferHelper.safeTransferFrom(address(jagerToken), msg.sender, address(this), amount); poolInfo.totalReward += amount; updatePool(); uint256 currentBlock = block.number; uint256 releaseBlockNumber = 7 days / 3; rewardPerBlock = (poolInfo.totalReward - poolInfo.releaseReward) / releaseBlockNumber; poolInfo.lastRewardBlock = currentBlock; endBlock = currentBlock + releaseBlockNumber; } ``` However, since this function is permissionless, a malicious actor could exploit it by repeatedly transferring minimal amounts (e.g., 1 wei) to reset the end block. This would artificially extend the reward distribution period, delaying users' ability to claim accumulated rewards. If the attacker continues this pattern every 7 days, the rewards could be fragmented into indefinitely small allocations over an extended timeframe, effectively locking funds in the pool for prolonged periods.
The cited address input is missing a check that it is not `address(0)`. ```solidity constructor(address jager, address sign ,address invitor) JagerHunterMint(3 days) { @> jagerToken = jager; lpStake = new JagerHunterLP(jager); TransferHelper.safeApprove(jager, address(lpStake), ~uint256(0)); @> signAddress = sign; @> defaultInvitor = invitor; } ```
The linked variables are assigned a value once and never modified, so they should be declared as `constant`. A significant advantage of using constant variables is that reading them is considerably less costly than accessing regular state variables. ```solidity uint256 public immutable firstInvitorRate = 900; uint256 public immutable secondInvitorRate = 300; uint256 public immutable instantRate = 6500; uint256 public immutable baseRate = 10000; ```
The report names a repository or files. Open the report to see its scope.
Repository and files the report names (3)
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