Introduction
We express our gratitude to the Europeum team for the collaborative engagement that enabled the execution of this Smart Contract Security Assessment.
Europeum operates and scales Europe’s sovereign digital trust infrastructure, enabling secure, transparent, and interoperable services across the public and private sectors.
Document | |
|---|---|
| Name | Smart Contract Code Review and Security Analysis Report for Europeum |
| Audited By | Seher Saylik |
| Approved By | Olesia Bilenka |
| Website | https://europeum.eu/→ |
| Changelog | 24/07/2026 - Preliminary Report |
| 03/08/2026 - Retest Report | |
| 14/08/2026 - Final Report | |
| Platform | Private Chain |
| Language | Solidity |
| Tags | Proxy, Upgradeability |
| Methodology | https://docs.hacken.io/methodologies/smart-contracts→ |
Document
- Name
- Smart Contract Code Review and Security Analysis Report for Europeum
- Audited By
- Seher Saylik
- Approved By
- Olesia Bilenka
- Website
- https://europeum.eu/→
- Changelog
- 24/07/2026 - Preliminary Report
- 03/08/2026 - Retest Report
- 14/08/2026 - Final Report
- Platform
- Private Chain
- Language
- Solidity
- Tags
- Proxy, Upgradeability
Review Scope | |
|---|---|
| Repository | https://gitlab.com/europeum/public/core-services/-/tree/main/→ |
| Initial Commit | 89bb63b |
| Retest | a64e313 |
| Final Commit | d1535ba |
Review Scope
- Initial Commit
- 89bb63b
- Retest
- a64e313
- Final Commit
- d1535ba
Audit Summary
The system users should acknowledge all the risks summed up in the risks section of the report
Documentation quality
The contracts contain NatSpec documentation explaining the versioning, ownership, registration, and opt-in upgrade model.
However, the package README describes an outdated proxy architecture and does not accurately reflect the current implementation, where version and ownership data are stored in the beacon.
Code quality
The code is concise and generally follows established Solidity conventions.
The development environment is configured, and custom errors are used consistently.
Test coverage
Code coverage of the project is 100% (branch coverage).
Deployment, initialization, version publication, proxy upgrades, deprecation, ownership transfers, access control, and multiple-user interactions are covered.
System Overview
Beacon Proxy is an upgrade pattern composed of the following contracts:
VersionedUpgradeableBeacon — an Ownable beacon that stores multiple implementation versions and, per proxy, the version that proxy is pinned to and the owner allowed to opt it into a new version. It has the following attributes:
Initial version:
1, set at deployment frominitialImplementation.A version can be marked deprecated via
deprecateVersion(version). This blocks opt-in upgrades throughupgradeProxyToVersionand, if the deprecated version is the current latest, also blocks new proxy registration throughregisterProxy. Proxies already pinned to that version continue to resolve to it.Any caller that hasn't pinned a version (version
0) resolves to the current latest version — this makes a plain OpenZeppelinBeaconProxypointed at this beacon behave exactly like it would against a standardUpgradeableBeacon.The beacon falls back to the latest implementation for any unregistered proxy so that a plain OpenZeppelin
BeaconProxypointed at it behaves exactly like a normal OZ upgradeable beacon, and this is considered acceptable because the network is permissioned — write access is gated behind DID registration, trusted-issuer authorization, or policy/governor checks at the API layer
VersionedBeaconProxy — an OpenZeppelin BeaconProxy that registers itself with the beacon at construction via registerProxy(owner_), pinning its resolved version and recording its owner on the beacon. It has the following attributes:
Version and ownership state live entirely on the beacon, keyed by the proxy's own address, not on the proxy itself.
Its beacon address is set once, immutably, at deployment and can never be changed afterward.
Privileged roles
The owner of the
VersionedUpgradeableBeaconcontract can publish new implementation versions (addVersion) and mark any version as deprecated (deprecateVersion). It cannot force any already-deployed proxy to change which implementation it resolves to — a proxy only moves to a different version when that proxy's own registered owner explicitly callsupgradeProxyToVersion. The beacon owner therefore does not have unilateral control over live proxies, only over which versions exist and are offered.The owner of a given proxy (set once via
registerProxyat deployment, transferable viatransferProxyOwnership) can opt that specific proxy into any available, non-deprecated version viaupgradeProxyToVersion, and can transfer that ownership to another account. This owner has no authority over the beacon's set of versions or over any other proxy registered to it — their control is scoped strictly to their own proxy.
Potential Risks
New VersionedBeaconProxy instances can adopt _latestVersion even when it is deprecated.
Upgrades and required state migrations cannot be executed atomically.
The beacon owner can publish arbitrary implementations and deprecate available versions.
Users deploying a plain OpenZeppelin BeaconProxy should understand that it intentionally operates in standard beacon mode: it remains unregistered and automatically follows the beacon’s latest implementation without per-proxy version pinning or opt-in upgrades.
Because addVersion allows a new storageLayoutHash to be registered with isBreakingChange = false, an incompatible implementation can be recorded as storage-compatible. Proxy owners that then call upgradeProxyToVersion with safeUpgrade = true may accept an unsafe upgrade and brick their proxy.
Findings
Code ― | Title | Status | Severity | |
|---|---|---|---|---|
| F-2026-1812 | Deprecating The Current latestVersion Doesn't Stop New Proxies From Adopting It | fixed | Low | |
| F-2026-1815 | Redundant State-Change Operations Are Permitted | fixed | Observation | |
| F-2026-1813 | Constructor Doesn't Validate initialImplementation != address(0) | fixed | Observation | |
| F-2026-1812 | No Contract-existence Check on Implementation Addresses | fixed | Observation | |
| F-2026-1877 | Immediate Ownership Transfers Can Permanently Lock Upgrade Authority | accepted | Observation | |
| F-2026-1877 | Interface Omits getVersionsCompatibility | fixed | Observation |
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/-/tree/main/contracts?ref_type=heads→ |
| Initial Commit | 89bb63b74e88c7e3b1602f4801d682e634b6a521 |
| Retest | a64e3139c3a139da5bc3ff81c4d25fb35212c7f2 |
| Final Commit | d1535bacb0ee03fc987339c58324b34c3db14687 |
| Whitepaper | N/A |
| Requirements | NatSpec |
| Technical Requirements | N/A |
Scope Details
- Initial Commit
- 89bb63b74e88c7e3b1602f4801d682e634b6a521
- Retest
- a64e3139c3a139da5bc3ff81c4d25fb35212c7f2
- Final Commit
- d1535bacb0ee03fc987339c58324b34c3db14687
- Whitepaper
- N/A
- Requirements
- NatSpec
- Technical Requirements
- N/A
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.