Introduction
We express our gratitude to the Europeum team for the collaborative engagement that enabled the execution of this Smart Contract Security Assessment.
The Timestamp service is an EVM-based smart contract system designed to provide proof-of-existence by storing cryptographic hash values on-chain. Deployed as part of the European Blockchain Services Infrastructure (EBSI), the contract enables subjects to timestamp hashes, organize them into versioned records, and manage record ownership through time-bound validity windows.
Document | |
|---|---|
| Name | Smart Contract Code Review and Security Analysis Report for Europeum |
| Audited By | Olesia Bilenka |
| Approved By | Ivan Bondar |
| Website | https://europeum.eu/→ |
| Changelog | 29/07/2026 - Preliminary Report |
| 13/08/2026 - Final Report | |
| Platform | EVM Compatible Chains |
| Language | Solidity |
| Tags | Storage; Upgradable; Proxy; Centralization |
| Methodology | https://docs.hacken.io/methodologies/smart-contracts→ |
Document
- Name
- Smart Contract Code Review and Security Analysis Report for Europeum
- Audited By
- Olesia Bilenka
- Approved By
- Ivan Bondar
- Website
- https://europeum.eu/→
- Changelog
- 29/07/2026 - Preliminary Report
- 13/08/2026 - Final Report
- Platform
- EVM Compatible Chains
- Language
- Solidity
- Tags
- Storage; Upgradable; Proxy; Centralization
Review Scope | |
|---|---|
| Repository | https://gitlab.com/europeum/public/core-services→ |
| Commit | 89bb63b |
| Remediation commit | d1535ba |
Review Scope
- Commit
- 89bb63b
- Remediation commit
- d1535ba
Audit Summary
The system users should acknowledge all the risks summed up in the risks section of the report
Documentation quality
Functional requirements are partially covered in external EBSI documentation.
Discrepancies exist between documented behavior and actual implementation (e.g., stored data fields, access control model).
Technical description of internal architecture and library interactions is not provided.
NatSpec comments are present but incomplete for complex internal functions.
Code quality
The code follows a modular library pattern for separation of concerns.
Standard upgradeability patterns from OpenZeppelin are utilized.
Storage gap is implemented for upgrade safety.
Loop patterns are now conditionally executed, reducing unnecessary iterations.
Test coverage
Code coverage of the project is 97.67% (line coverage).
Branch coverage measurement is not configured in the project's test infrastructure.
Deployment and basic user interactions are covered with tests.
Some negative cases and edge conditions are not thoroughly covered.
Multi-user interaction scenarios with complex ownership transfers lack comprehensive testing.
System Overview
The system is built around an upgradeable proxy architecture using OpenZeppelin's Initializable pattern. The main Timestamp contract serves as the entry point and delegates business logic to three specialized libraries: HashAlgoLib for hash algorithm registry management, TimestampLib for standalone timestamp operations, and RecordLib for versioned record and ownership management. All administrative functions are gated through an external IPolicyRegistry contract that performs attribute-based access control checks.
The contract supports two primary workflows. First, standalone timestamping allows any caller to record up to three hash values per transaction, storing the hash, algorithm identifier, block number, and optional metadata. Second, record-based timestamping organizes timestamps into versioned records with multi-owner management. Each record maintains a version history where timestamps can be added, appended, or detached. Ownership is enforced through validity windows (notBefore/notAfter timestamps) with support for revocation.
Data retrieval is implemented with pagination utilities from the @ebsiint-sc/bootstrap package, supporting paginated queries across hash algorithms, timestamps, records, and versions. The contract maintains multiple index mappings to enable efficient lookups by owner, timestamp, or first-version hash.
Timestamp.sol — The main upgradeable implementation contract that exposes all external functions for hash algorithm management, timestamping, record creation, version management, and ownership operations. Business logic is delegated to the three libraries, and policy-based access control is enforced via
policyRegistryContract.libraries/HashAlgoLib.sol — A library responsible for managing the registry of supported hash algorithms. Functions
insertHashAlgorithmandupdateHashAlgorithmare provided for registration and modification, IANA name uniqueness is enforced, and paginated retrieval of algorithm IDs is exposed.libraries/RecordLib.sol — A library that manages records, versions, and ownership. Record creation is handled via
timestampRecordHashes, version creation viatimestampVersionHashesandtimestampRecordVersionHashes, hash appending to existing versions, timestamp detachment, and owner insertion/revocation with time-bound validity checks.libraries/TimestampLib.sol — A library responsible for creating and retrieving timestamps. Hash algorithm status is validated, timestamp IDs are computed as SHA256 of hash values, timestamp metadata (sender, block number, optional data) is stored, and duplicate timestamps with mismatched algorithms are prevented.
Privileged roles
Timestamp.sol
TS:insertHashAlgorithm policy holder: Accounts authorized by the external
IPolicyRegistryfor theTS:insertHashAlgorithmattribute.Can call
insertHashAlgorithmto register new hash algorithms with specified output length, IANA name, OID, status, and multihash representation.
TS:updateHashAlgorithm policy holder: Accounts authorized by the external
IPolicyRegistryfor theTS:updateHashAlgorithmattribute.Can call
updateHashAlgorithmto modify existing hash algorithm metadata including status changes.
Record Owner: Any address registered as an active owner of a specific record, within its validity window (
notBefore\<=block.timestamp\<=notAfter) and not revoked.Can call
timestampVersionHashesto add a new version with timestamps to a record identified by version hash.Can call
timestampRecordVersionHashesto add a new version with timestamps to a record identified by record ID.Can call
appendRecordVersionHashesto append timestamps to an existing version.Can call
insertRecordVersionInfoto add metadata to an existing version.Can call
detachRecordVersionHashto remove a timestamp from a version.Can call
insertRecordOwnerto add new owners with specified validity windows.Can call
revokeRecordOwnerto revoke existing owners (including self-revocation).
Potential Risks
Critical trust in policy registry for hash algorithm governance: The TS:insertHashAlgorithm and TS:updateHashAlgorithm policy attributes in Timestamp gate all hash algorithm management through the external policyRegistryContract. A compromised or malicious policy registry administrator could register arbitrary hash algorithms with misleading parameters, or change the status of existing algorithms to inactive, thereby preventing new timestamps from being created with those algorithms. The Timestamp contract does not control its own authorization semantics for administrative functions; correctness and security of hash algorithm management depend entirely on the external registry's implementation.
Immutable dependency on policy registry address: The policyRegistryContract reference in Timestamp is assigned during initialize with no administrative function to update it. If the policy registry contract becomes compromised, deprecated, or requires migration, the Timestamp contract implementation must be upgraded to point to a new registry, potentially disrupting service continuity.
Reliance on EBSI bootstrap libraries for core functionality: The Timestamp contract depends on external EBSI bootstrap libraries including Pagination for paginated queries, StringManip for address-to-string conversion in RecordLib, and ImplementationInitSelector for upgrade introspection. Vulnerabilities or behavioral changes in these libraries would propagate to all dependent functionality across hash algorithm retrieval, record ownership management, and pagination of timestamps.
Hash algorithm metadata remains mutable after timestamp creation: The updateHashAlgorithm function in HashAlgoLib permits modification of hash algorithm properties including outputLength, ianaName, oid, status, and multiHash for any previously registered algorithm ID. Timestamps referencing a given algorithm ID retain only the numeric identifier, not a snapshot of the algorithm metadata at creation time. Retroactive changes to algorithm metadata could cause historical timestamps to be interpreted inconsistently.
Timestamp-record associations are removable: The detachRecordVersionHash function in RecordLib allows record owners to remove timestamp associations from record versions. While the underlying timestamp data persists in the global timestampsStore, the linkage to the record is severed, potentially affecting the auditability and traceability of timestamped records.
Time-bounded ownership creates temporal access windows: Record ownership in RecordLib is governed by notBefore and notAfter timestamps checked in checkIfOwnerExist. The validity window is evaluated against block.timestamp, meaning owners can only perform record modifications within their designated time range. Incorrectly configured ownership periods could inadvertently lock records from modification or grant premature access.
Self-referential owner revocation: The revokeRecordOwner function in RecordLib requires the caller to be a current valid owner via checkIfOwnerExist. An owner may revoke other owners or themselves, and if all owners become revoked, the record becomes permanently unmodifiable as no address would satisfy the ownership check.
Proxy deployment pattern indicated by storage gap: The Timestamp contract includes a uint256[50] private __gap storage reservation and inherits Initializable with _disableInitializers in the constructor, indicating deployment behind a proxy. The security of stored timestamps, records, and hash algorithms depends on the proxy contract's access control for implementation upgrades, which is outside the audited scope.
Findings
Code ― | Title | Status | Severity | |
|---|---|---|---|---|
| F-2026-1817 | Out-of-Bounds Array Access in insertRecordOwner Permanently Breaks Owner Re-Addition | fixed | High | |
| F-2026-1823 | Functions timestampHashes and timestampRecordHashes Lack Policy Registry Check Allowing Unrestricted Timestamp and Record Creation | accepted | High | |
| F-2026-1824 | Unconditional Global Index Cleanup in detachRecordVersionHash Causes Irreversible Data Corruption | fixed | High | |
| F-2026-1817 | Missing State Cleanup in detachRecordVersionHash Breaks Timestamp Re-attachment to Records | fixed | Medium | |
| F-2026-1824 | Record Management Functions Lack Policy Registry Check Relying Only on Ownership Verification | accepted | Medium | |
| F-2026-1818 | Inconsistent versionInfo Deduplication Logic Across Record Functions | fixed | Low | |
| F-2026-1818 | Self-Revocation in revokeRecordOwner Can Permanently Orphan Records | fixed | Low | |
| F-2026-1824 | Detaching All Timestamps From a Version Renders Version Data Permanently Inaccessible | fixed | Low | |
| F-2026-1824 | Low Case-Sensitivity Inconsistency for Owner IDs Results in Potential Lookup Failures | accepted | Low | |
| F-2026-1824 | Front-Running Risk in timestampHashes Allows Adversaries to Capture Proof-of-Existence Attribution | fixed | Low |
Appendix 1. Definitions
Severities
When auditing smart contracts, Hacken is using a risk-based approach that considers Likelihood, Impact, Exploitability and Complexity metrics to evaluate findings and score severities.
Reference on how risk scoring is done is available through the repository in our Github organization:
Severity | Description |
|---|---|
Critical | Critical vulnerabilities are usually straightforward to exploit and can lead to the loss of user funds or contract state manipulation. |
High | High vulnerabilities are usually harder to exploit, requiring specific conditions, or have a more limited scope, but can still lead to the loss of user funds or contract state manipulation. |
Medium | Medium vulnerabilities are usually limited to state manipulations and, in most cases, cannot lead to asset loss. Contradictions and requirements violations. Major deviations from best practices are also in this category. |
Low | Major deviations from best practices or major Gas inefficiency. These issues will not have a significant impact on code execution. |
Severity
- Critical
Description
- Critical vulnerabilities are usually straightforward to exploit and can lead to the loss of user funds or contract state manipulation.
Severity
- High
Description
- High vulnerabilities are usually harder to exploit, requiring specific conditions, or have a more limited scope, but can still lead to the loss of user funds or contract state manipulation.
Severity
- Medium
Description
- Medium vulnerabilities are usually limited to state manipulations and, in most cases, cannot lead to asset loss. Contradictions and requirements violations. Major deviations from best practices are also in this category.
Severity
- Low
Description
- Major deviations from best practices or major Gas inefficiency. These issues will not have a significant impact on code execution.
Potential Risks
The "Potential Risks" section identifies issues that are not direct security vulnerabilities but could still affect the project’s performance, reliability, or user trust. These risks arise from design choices, architectural decisions, or operational practices that, while not immediately exploitable, may lead to problems under certain conditions. Additionally, potential risks can impact the quality of the audit itself, as they may involve external factors or components beyond the scope of the audit, leading to incomplete assessments or oversight of key areas. This section aims to provide a broader perspective on factors that could affect the project's long-term security, functionality, and the comprehensiveness of the audit findings.
Appendix 2. Scope
The scope of the project includes the following smart contracts from the provided repository:
Scope Details | |
|---|---|
| Repository | https://gitlab.com/europeum/public/core-services→ |
| Commit | 89bb63b74e88c7e3b1602f4801d682e634b6a521 |
| Remediation commit | d1535bacb0ee03fc987339c58324b34c3db14687 |
| Requirements | https://hub.ebsi.eu/docs/use-cases/anchoring/timestamp/timestamp-introduction→ |
Scope Details
- Commit
- 89bb63b74e88c7e3b1602f4801d682e634b6a521
- Remediation commit
- d1535bacb0ee03fc987339c58324b34c3db14687
Assets in Scope
Appendix 3. Additional Valuables
Additional Recommendations
The smart contracts in the scope of this audit could benefit from the introduction of automatic emergency actions for critical activities, such as unauthorized operations like ownership changes or proxy upgrades, as well as unexpected fund manipulations, including large withdrawals or minting events. Adding such mechanisms would enable the protocol to react automatically to unusual activity, ensuring that the contract remains secure and functions as intended.
To improve functionality, these emergency actions could be designed to trigger under specific conditions, such as:
Detecting changes to ownership or critical permissions.
Monitoring large or unexpected transactions and minting events.
Pausing operations when irregularities are identified.
These enhancements would provide an added layer of security, making the contract more robust and better equipped to handle unexpected situations while maintaining smooth operations.
Frameworks and Methodologies
This security assessment was conducted in alignment with recognised penetration testing standards, methodologies and guidelines, including the NIST SP 800-115 – Technical Guide to Information Security Testing and Assessment →, and the Penetration Testing Execution Standard (PTES) →, These assets provide a structured foundation for planning, executing, and documenting technical evaluations such as vulnerability assessments, exploitation activities, and security code reviews. Hacken’s internal penetration testing methodology extends these principles to Web2 and Web3 environments to ensure consistency, repeatability, and verifiable outcomes.