Join 1500+ leaders who secured themselves from losing Billion Dollars



Zoniqx, a Silicon Valley fintech, asked us to audit the reference implementation of ERC-7518, a security-token standard its own engineers authored and proposed to the Ethereum community. This was a pilot engagement, and an unusual one. Most audits look at a single application. ERC-7518 is meant to be the rulebook that other tokenization platforms build on, so a flaw here wouldn’t hurt one protocol. It would echo into every asset ever issued on top of it.
Over eight days in May 2024 we reviewed 18 contracts spanning the token core, its compliance modules and its marketplace. We came back with 17 findings, four of them high severity. These included an allowance bug that would have let a delegated operator move ten times their authorized amount, and a side door that let locked tokens escape through the batch-transfer function. Zoniqx’s team fixed sixteen of the seventeen findings. The last was partially resolved, with the residual risk documented and accepted. Every fix was verified in a second review round on 29 May 2024.
| Client | Zoniqx Inc. (formerly Tassets), tokenization infrastructure, Silicon Valley |
| Subject | Reference implementation of ERC-7518 “DyCIST” (Dynamic Compliant Interoperable Security Token) |
| Engagement type | Pilot audit: the first independent security review of the standard’s implementation |
| Chain | EVM (Solidity, upgradeable OpenZeppelin-based architecture) |
| Timeline | 6–13 May 2024, updated code received 28 May, second review 29 May |
| Scope | 18 contracts: token core, compliance & control modules, marketplace, oracle interface |
| Method | Manual review, functional testing with runnable proof-of-concepts, automated analysis, with every automated flag re-checked by hand |
| Result | 17 findings: 4 high, 5 low, 8 informational. 16 resolved and verified, 1 partially resolved |
Zoniqx builds Tokenized Asset Lifecycle Management (TALM) infrastructure: the plumbing that lets institutions turn real estate, private equity, bonds and other real-world assets into tokens that can be issued, managed and traded on-chain without stepping outside regulatory lines. Instead of keeping that know-how behind closed doors, the team distilled it into a proposed Ethereum standard, ERC-7518, and open-sourced the reference implementation. Our pilot audit covered that codebase on its main branch.
ERC-7518, the Dynamic Compliant Interoperable Security Token standard, shortened to DyCIST, was proposed to the Ethereum community in September 2023 by four Zoniqx engineers. It starts from ERC-1155, the multi-token standard, and adds the controls that regulated assets can’t live without. Four ideas do most of the work:
canTransfer check validates that voucher before any tokens move. When regulation changes, the off-chain policy changes and the contract doesn’t have to be redeployed.freeze an address, restrictTransfer on a partition, lockTokens until a release time, forceTransfer for court orders or lost-key recovery, and payout / batchPayout for dividends and coupons.ERC-7518 tries to do for security tokens what ERC-20 did for utility tokens: give everyone one agreed way to build. That’s precisely why its implementation deserved an audit of its own.

The audit covered the complete ERC-7518 reference suite: the token core itself, the pluggable compliance and control modules it inherits, the marketplace contract that sits on top, and the Chainlink interface used for price data. The token contract (ERC7518.sol) is where the standard’s promises live—voucher-checked transfers, locking, freezing, force transfers and payouts—so it got the deepest attention.

| Component | What it does |
|---|---|
| ERC7518.sol, ERC1155Mod.sol, STOBaseV2.sol | The token core: partitioned ERC-1155 balances, transfer gating, issuance and settlement logic for offerings |
| CompliTo.sol (+ ICompliTo.sol) | Compliance oracle: verifies the off-chain vouchers that authorize regulated transfers |
| FreezeAddress.sol, RestrictTransfer.sol, TokenLock.sol | The enforcement trio: address freezing, partition-level transfer restrictions, time-locked balances |
| Payout.sol, PaymentTracker.sol | Dividend/coupon distribution and investment bookkeeping |
| IssuerFactory.sol, Nonce.sol, ERC1155AllowanceWrapper.sol, ERC1155Permit.sol, ERC2771Context(Upgradeable).sol | Supporting machinery: issuer onboarding, signature nonces, per-partition allowances, permits and meta-transaction context |
| ERC7518MarketPlace.sol (+ IMarketPlace.sol), AggregatorV3Interface.sol | Primary/secondary marketplace and the Chainlink price-feed interface |
Because this was a pilot, the first independent security review of the standard’s implementation, we set the engagement up a little differently from a routine token audit. Two choices mattered most: we audited against the published EIP-7518 specification, not just against general best practice, so “the code does X but the standard says it MUST do Y” counted as a finding. And every high-severity claim had to ship with a runnable proof-of-concept, so Zoniqx’s engineers and their future reviewers could watch the attack happen rather than take our word for it.
Seventeen findings in total: four high severity, five low, eight informational. Sixteen were fully resolved and verified in the second review. One high-severity item, covering gaps in the freeze logic, was partially resolved, with the remaining edge cases documented and consciously accepted by the client.

How to read the severities. High means exploitable: the contract can be made to do something its design forbids, and it must be fixed before mainnet. Low means minor impact: worth fixing, not an emergency. Informational means code-quality, documentation or style improvements that make the system safer to maintain and integrate.
The low and informational findings included missing input validation, a missing re-entrancy guard on batchPayout(), thin NatSpec documentation, events that didn’t say enough, and a typo in an interface. The four high-severity findings each struck at a capability the standard exists to provide.
High severity · Resolved
Where: ERC7518.sol :: safeTransferFrom and ERC1155AllowanceWrapper.sol :: _spendAllowance.
ERC-7518 lets an owner delegate limited transfer rights to an operator, say a broker allowed to move up to 100 tokens of a given partition. We found the code checked that allowance against the wrong token: safeTransferFrom passed a hardcoded 0 as the token ID instead of the ID actually being transferred, and inside _spendAllowance the amount and ID parameters were swapped. The net effect: the allowance check was being run against a partition the operator may never have been approved for.
The attack, as we demonstrated it: Alice approves Bob to manage 100 tokens of partition 1. Bob calls the transfer function asking to move 1,000. Because the allowance is debited against the wrong token ID, the check passes, and Bob walks away with ten times his authorization, straight to Charlie’s wallet.
1// Alice approved Bob for 100 tokens of id1. Bob moves 1000 instead.
2erc1155Contract.safeTransferFrom(aliceAddress, charlieAddress, id1, 1000, data);The fix: Pass the real token ID through the whole call chain and un-swap the parameters, so allowance is verified and debited against the exact partition being moved. Verified in the second review.
High severity · Resolved
Where: TokenLock.sol :: lockTokens.
Token locking exists for vesting schedules and holding periods, a legitimate, regulated feature. But the function that triggers it checked only that the target account had enough transferable balance. It never asked who was calling. Any address on the network could lock any amount of any other user’s tokens, for any duration.
The attack, as we demonstrated it: A stranger picks a victim’s address and token ID and locks 90 of their tokens for a day, freezing assets the victim still owns and should control. Repeated at scale, this is a denial-of-service against every holder of the token, and for a platform courting regulated issuers, assets frozen by random outsiders is a compliance incident.
The fix: Authorization checks so only the token owner or an explicitly delegated role can initiate a lock, backed by role-based access control for this and similar sensitive operations. Verified in the second review.
High severity · Partially resolved
Where: ERC7518.sol :: freeze and its interaction with privileged roles.
Freezing is the emergency brake: the function a compliance team reaches for when a court order lands or an address is sanctioned. The EIP-7518 specification states that a frozen address must not transfer and must not receive payouts. We tested the implementation against those MUST statements and found three gaps. A frozen account could still have its funds force-transferred out by an authorized role. A frozen account could still receive payouts, with profits flowing into an address that had supposedly been cut off. And the freeze could be turned on the privileged roles themselves—admin, minter, paying agent—opening the door to the platform locking its own keys in the car.
We confirmed each gap with a dedicated test, quoting the specification line it violated.
The fix: Access-control and state checks were tightened so frozen addresses are excluded from transfers and payouts, and privileged operational roles are protected from being frozen into inactivity. One edge case in the role matrix remains consciously accepted by the client. It is documented in the report, which is why this item is marked partially resolved.
High severity · Resolved
Where: ERC7518.sol :: safeBatchTransferFrom.
Zoniqx had done the right thing on the single-transfer path: safeTransferFrom was overridden with the full canTransfer ceremony—compliance voucher, freeze checks, lock checks, signatures. But safeBatchTransferFrom, the plural version of the same function, was inherited straight from the OpenZeppelin base contract with none of those checks. The front door had a guard, but the side door was propped open.
The attack, as we demonstrated it: We locked several accounts’ tokens for three days, then immediately moved those same locked balances out via safeBatchTransferFrom with no voucher, no signature, no complaint from the contract. Every guarantee the locking module was built to enforce evaporated the moment a transfer arrived in batches.
The fix: Route batch transfers through the same compliance and lock checks as single transfers, so the two paths can’t drift apart. Verified in the second review.
Zoniqx’s engineers moved fast. Updated code came back within two weeks of the report, and our second review on 29 May 2024 confirmed that 16 of the 17 findings were fully resolved, including all five low-severity and all eight informational items. The improvements also included input validation on payout addresses, a re-entrancy guard on batchPayout(), proper NatSpec documentation, and events that let an auditor reconstruct what happened. These changes make the codebase safer to maintain and integrate.
A security audit identifies and mitigates risk at a point in time. It cannot guarantee protection against every possible threat. This case study summarizes the May 2024 pilot audit of the Zoniqx ERC-7518 contracts as delivered to the client. The full audit report remains the authoritative record of scope, findings and resolution status.
From day-zero risk mapping to exchange-ready audits, QuillAudits helps projects grow with confidence. Smart contracts, dApps, infrastructure, compliance: secured end to end.