ArbDoge AI

CertiKFiles named in the report

CertiK reviewed AIDOGE (ArbDoge AI) on 20 Jul 2023: 22 findings, 1 critical; 9 marked fixed, 13 open.

1 critical finding, fixed
Open the reportOpen AIDOGE’s security record

Report hosted on skynet.certik.com.

Trustblock does not review code.

Findings22

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

SeverityOpenAcknowledgedFixed
Critical001
High202
Medium000
Low1106
HighCentralization Related Risks in `DogeBonusPool.soOpen

In the contract `DogeBonusPool` the role `_owner` has authority over the functions shown in the diagram below. Any compromise to the `_owner` account may allow the hacker to take advantage of this authority and add pools, set pools, update `_callers`, stop distributing rewards, and update other state variables. ![](https://accelerator-tasks-prod.acc.corp.certik.com/002489e5a79343b8b06caec7e7ff64a4/diagrams/centralization_DogeBonusPool-DogeBonusPool-_owner.svg) In the contract `DogeBonusPool` the role `_callers` has authority over the functions `injectRewards()` and `injectRewardsWithTime()`. Any compromise to the `_callers` account may allow the hacker to take advantage of this authority and decrease the rewards per second. In the contract `DogeBurnPool` the role `_owner` has authority over the functions shown in the diagram below. Any compromise to the `_owner` account may allow the hacker to take advantage of this authority and set `govWallet`, `govRate`, and `epochReward`. ![](https://accelerator-tasks-prod.acc.corp.certik.com/002489e5a79343b8b06caec7e7ff64a4/diagrams/centralization_DogeBurnPool-DogeBurnPool-_owner.svg)

HighInitial Token DistributionOpen

In the contract `AIDoge`, all tokens are sent to the contract deployer when deploying the contract. This is a potential centralization risk as the deployer can distribute tokens without the consensus of the community.

LowCostly Function `pendingReward()`Open

```solidity=100 function pendingReward(address _user) public view returns (uint256 rewards) { uint256 epoch = currentEpoch(); uint256 lastClaimEpoch = userLastClaimEpoch[_user]; if(epoch > lastClaimEpoch) { uint ct = epoch - lastClaimEpoch; for (uint i = 0; i < ct; i++) { uint256 rewardsPerShare = epochRewardsPerShare[lastClaimEpoch + i]; uint256 loopEpoch = lastClaimEpoch + i; if (loopEpoch >= lastSettleEpoch) { uint256 burned = epochBurned[loopEpoch]; if (burned == 0) continue; rewardsPerShare = epochReward.mul(1e12).div(burned); } rewards = rewards.add(userBurned[loopEpoch][_user].mul(rewardsPerShare).div(1e12)); } } } ``` The `pendingReward()` function is used to calculate a user's rewards. However, it can be very costly in terms of gas consumption to calculate rewards for a user who has never claimed rewards before. This is because the loop within the function would iterate from the user's `userLastClaimEpoch`, which is initialized as 0.

LowDuplicate Code in `setFeeReceivers()`Open

```solidity=356 function setFeeReceivers( address _gov1Wallet, address _gov2Wallet, address _bonusWallet, address _jackpotWallet, address _devWallet ) external onlyOwner { gov1Wallet = _gov1Wallet; gov2Wallet = _gov2Wallet; bonusWallet = _bonusWallet; jackpotWallet = IJackpot(_jackpotWallet); devWallet = _devWallet; devWallet = _devWallet; } ``` In the `setFeeReceivers()` function, there is a duplicate line of code that assigns the `_devWallet` value to the `devWallet` state variable. This duplicate line of code does not affect the functionality.

LowInaccurate Fee Collection and Distribution Due toOpen

The functions `setBuyFees()` and `setSellFees()` do not correctly add up all fees to `totalFeeBuy` and `totalFeeSell` respectively. This issue could result in reduced fee collection and adversely affect the distribution of fees among various recipients

LowIncorrect Reward Multiplier Calculation in `getMuOpen

```solidity=92 function getMultiplier(uint256 _from, uint256 _to) public view returns (uint256) { if (_to <= bonusEndTime) { return _to.sub(_from).mul(BONUS_MULTIPLIER); } else if (_from >= bonusEndTime) { return 0; } else { return bonusEndTime.sub(_from).mul(BONUS_MULTIPLIER); } } ``` The `getMultiplier()` function is used to calculate the reward multiplier for the period between `_from` and `_to`. The rewards should be calculated from `startTime`. However, the function does not check if `_from` is less than `startTime` and uses `_to.sub(_from)` to calculate the elapsed time. This may result in incorrect values if `_from` is less than `startTime`. This is an informational issue because the parameters are checked in the upper function of calling `getMultiplier()`. However, if users directly call the view function, they may receive inaccurate return values.

LowIncorrect User Information Returned for Invalid TOpen

```solidity=340 function getUserView(address token, address account) public view returns (UserView memory) { uint256 pid = LpOfPid[token]; UserInfo memory user = userInfo[pid][account]; uint256 unclaimedRewards = pendingReward(pid, account); uint256 lpBalance = IERC20(token).balanceOf(account); return UserView({ stakedAmount: user.amount, unclaimedRewards: unclaimedRewards, lpBalance: lpBalance }); } ``` The `getUserView()` function is used to view a user's information on a specific token's pool. The function first retrieves the `pid` (pool's id) from the `LpOfPid` mapping, and then retrieves the user's information on the pool with `pid`. For the first deposit token, its `pid` is 0. However, all invalid tokens' `pid` in the `LpOfPid` mapping are also 0. This results in the function returning incorrect values for invalid tokens.

LowMissing Zero Address ValidationOpen

Addresses are not validated before assignment or external calls, potentially allowing the use of zero addresses and leading to unexpected behavior or vulnerabilities. For example, transferring tokens to a zero address can result in a permanent loss of those tokens. ```solidity=64 govWallet = _govWallet; ``` - `_govWallet` is not zero-checked before being used. --- ```solidity=363 gov1Wallet = _gov1Wallet; ``` - `_gov1Wallet` is not zero-checked before being used. --- ```solidity=364 gov2Wallet = _gov2Wallet; ``` - `_gov2Wallet` is not zero-checked before being used. --- ```solidity=365 bonusWallet = _bonusWallet; ``` - `_bonusWallet` is not zero-checked before being used. --- ```solidity=368 devWallet = _devWallet; ``` - `_devWallet` is not zero-checked before being used.

LowNo Upper Limit in fee setting functionsOpen

There are no upper boundaries for the `setBuyFees()` and `setSellFees()` functions which are used to set buy and sell fees. It is possible to set the total fee rate up to any arbitrary amount. If the fees exceed 100%, all buy and sell transactions would fail, disrupting the functionality of the contract.

LowOut of Scope DependencyOpen

The contract is serving as the underlying entity to interact with third-party or out-of-scope protocols. The scope of the audit treats third party entities as black boxes and assumes their functional correctness. However, in the real world, third parties can be compromised and this may lead to lost or stolen assets. --- ```solidity=40 IMintableERC20 public rewardToken; ``` - The contract `DogeBurnPool` interacts with third party contract with `IMintableERC20` interface via `rewardToken`. --- ```solidity=70 address private bonusWallet; ``` - The contract `AIDoge` interacts with third party contract with `IDogeBonusPool` interface via `bonusWallet`. --- ```solidity=71 IJackpot public jackpotWallet; // https://arbiscan.io/address/0x7c5f84bc89f7cf93e0cf5c293c5e5a03a3527f99#code ``` - The contract `AIDoge` interacts with out-of-scope contract with `IJackpot` interface via `jackpotWallet`. --- ```solidity=79 ICamelotFactory private immutable factory; ``` - The contract `AIDoge` interacts with third party contract with `ICamelotFactory` interface via `factory`. --- ```solidity=80 ICamelotRouter private immutable swapRouter; ``` - The contract `AIDoge` interacts with third party contract with `ICamelotRouter` interface via `swapRouter`. --- ```solidity=81 IWETH private immutable WETH; ``` - The contract `AIDoge` interacts with third party contract with `IWETH` interface via `WETH`.

Show 3 more
LowPotential Loss of Rewards Due to Remaining RewardOpen

In the `_injectRewardsWithTime()` function, the variable `remainingBal`, representing the total rewards, will be updated to 0 if `bonusEndTime <= block.timestamp`. This may result in reward loss if the following scenario occurs.

LowPotential Unfair Reward Distribution Related to `Open

```solidity=305 function emergencyRewardWithdraw(uint256 _amount) public onlyOwner { require(_amount <= rewardToken.balanceOf(address(this)), 'DogeBonusPool: not enough token'); rewardToken.safeTransfer(address(msg.sender), _amount); } ``` The `emergencyRewardWithdraw()` function is used to withdraw reward tokens without decreasing the total rewards and updating the pools. Due to the actual rewards being fewer than the calculated rewards, the rewards will not be fairly distributed. This could result in a first-come, first-served reward distribution.

LowPotential Unreasonably Small Reward RatesOpen

The `_injectRewardsWithTime()` function is utilized to add rewards to the contract, taking the parameter `rewardsSeconds` to extend the remaining reward time. However, if the `rewardsSeconds` value is unreasonably large, the `rewardsPerSecond` (representing the reward earned per second of staking), which is calculated by dividing total rewards by the remaining reward time, can become extremely small. This may lead to reduced incentives for staking.

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 (5)

  • contracts/pool/DogeBonusPool.sol
  • contracts/pool/DogeBurnPool.sol
  • contracts/DogeBurnPool.sol
  • contracts/DogeBonusPool.sol
  • contracts/token/AIDoge.sol

Part of AIDOGE’s security record

AIDOGE
Audits2 audits by 1 firmLast audit Aug 2023, by CertiK.
Critical findingsNo open critical findingsAcross the 2 reports, 1 critical finding was reported. It is marked fixed by the firm that reported it.
Open AIDOGE’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