As of 3 Nov 2026, Ordinal Doge has 1 audit report on Trustblock, by CertiK, dated 20 Apr 2023. That report lists no open critical findings. It also holds 2 deployed contracts on 1 chain.
Record last updated . It holds audits, findings and contracts up to Nov 2026, and incidents up to Oct 2026. Trustblock does not review code.
Newest first
Statuses are the security firm’s own, from each report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 0 |
| High | 0 | 1 | 0 |
| Medium | 0 | 3 | 0 |
| Low | 0 | 7 | 1 |
Code inside the constructor is only executed during the deployment of the contract and only affects the state of the implementation contract. Therefore, it will never be executed in the context of the proxy’s state which makes it irrelevant for an upgradeable contract.
Open the reportAlthough the contract `TokenVault` implements the contract `ERC721HolderUpgradeable` to receive the ERC-721 tokens for auction, it does not explicitly calls the function `IERC721(token).transferFrom` to transfer the ERC-721 tokens to the current contract address. Thus, the winners may not able to get the auction token in the function `end()`. The function `initialize()` only set the token address and id, but does not transfer the token ownership to the contract address. Since the function `initialize()` can be called by anyone, anyone can create the auction and become the `curator` even if he/she is not the token owner.
Open the reportIn the Ethereum, `send/transfer/call` can be used for ETH transferrings. In the worst case, the fallback function can only rely on 2300 gas being available (for example when `send` or `transfer` is used), leaving little room to perform other operations except basic logging. Therefore, the fallback function of the current contract is not suitable for doing much. The contract `InitializedProxy` will make a delegate call to the `_impl` contract, which may cause the out-of-gas error. ```solidity fallback() external payable { address _impl = logic; assembly { let ptr := mload(0x40) calldatacopy(ptr, 0, calldatasize()) let result := delegatecall(gas(), _impl, ptr, calldatasize(), 0, 0) let size := returndatasize() returndatacopy(ptr, 0, size) switch result case 0 { revert(ptr, size) } default { return(ptr, size) } } } ```
Open the reportThe implementation of the `isContract` check can not cover all scenarios. The check can be bypassed if the call is from the constructor of a smart contract or when the contract is destroyed. In that case, the codesize will also be zero. The "isContract" function in the OpenZeppelin "Address" library uses the same implementation, but comments mention that "it's unsafe to rely on the check and it can be bypassed". Reference: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol.
Open the reportPerforming integer division before multiplication truncates the low bits, losing the precision of calculation. ```solidity=210 uint256 feePerSecond = currentAnnualFee / 31536000; ``` ```solidity=214 uint256 curatorMint = sinceLastClaim * feePerSecond; ``` --- ```solidity=220 feePerSecond = currentAnnualFee / 31536000; ``` ```solidity=221 uint256 govMint = sinceLastClaim * feePerSecond; ``` --- ```solidity=251 uint256 averageReserve = reserveTotal / votingTokens; ``` ```solidity=253 uint256 reservePriceMin = averageReserve * ISettings(settings).minReserveFactor() / 1000; ``` --- ```solidity=268 uint256 averageReserve = (reserveTotal - (old * weight)) / (votingTokens - weight); ``` ```solidity=270 uint256 reservePriceMin = averageReserve * ISettings(settings).minReserveFactor() / 1000; ```
Open the reportThe function `initialize()` does not contain the necessary boundary checks for `fee`. Also, the variable `maxCuratorFee` does not have a reasonable boundary.
Open the reportThe contract `TokenVault` is an ERC20 token. The holders of this token can propose the auction price of a certain ERC721 token, with the holding balance as the voting weight. The final auction start price will be the average of the proposed prices. The one who calls the function `initialize()` will mint the initial tokens to the `curator` and set the initial price for the `curator`. The token can be transferred and the voted price will be changed because of the balance changes. If the auction is successfully ended, all the holders can get the ETH from the auction in proportion to the user balance. If the `curator` does not perform any transfer, only the `curator` and the `govAddress` will get the price voting power by claiming fees. However, the newly minted tokens do not automatically contribute to the price voting. In the code snippet below, the `if` condition `_from != address(0)` will skip the voting price update for mint. ```solidity=287 function _beforeTokenTransfer(address _from, address _to, uint256 _amount) internal virtual override { if (_from != address(0) && auctionState == State.inactive) { ... //CetiK comment: update the voting price based on new balances ```
Open the reportAddresses should be checked before assignment or external call to make sure they are not zero addresses. ```solidity=106 settings = _settings; ``` - `_settings` is not zero-checked before being used. --- ```solidity=114 token = _token; ``` - `_token` is not zero-checked before being used. --- ```solidity=118 curator = _curator; ``` - `_curator` is not zero-checked before being used. --- ```solidity=146 curator = _curator; ``` - `_curator` is not zero-checked before being used. --- ```solidity=175 curator = _curator; ``` - `_curator` is not zero-checked before being used.
Open the reportIt is highly recommended NOT to include OpenZeppelin library code directly in source code, but import the original library to minimize risk because even slight changes to the library code may lead to critical/major vulnerabilities/bugs. For Solidity version 0.6.x, the latest OpenZeppelin version 3.4.2 should be used.
Open the reportSince there is no access restriction on the function `initialize()`, malicious hackers can execute the function `initialize()` to get the `curator` role, get new ERC20 tokens minted, and set a new auction price.
Open the reportThe variable `vaultClosed` is declared but not used. ```solidity=75 bool public vaultClosed; ```
Open the report| Address | Chain | Source code |
|---|---|---|
| 0x7b0f…3dca0x7b0fce54574d9746414d11367f54c9ab94e53dca | Chain: Ethereum | Source code: Verified source |
| 0x796a…eabc0x796a4503b444a71b331c9556bef0815237ddeabc | Chain: Ethereum | Source code: Verified source |
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.
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.
<head><script src="https://widget.trustblock.run/project-widget.min.js" defer></script></head><body><divdata-tb-project-widgetdata-tb-project-slug="ordinal-doge"></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