CertiK reviewed Quadrata (Quadrata Passport Audit 2) on 23 Sep 2022: 12 findings, 0 critical; 6 marked fixed, 6 acknowledged.
Report hosted on skynet.certik.com.
Trustblock does not review code.
Statuses are the security firm’s own, from its report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 0 |
| High | 0 | 2 | 1 |
| Medium | 0 | 2 | 1 |
| Low | 0 | 2 | 4 |
An issuer could mistakenly burn a passport with valid attributes through the function `burnPassportsIssuer()`. In the following statements, if `msg.sender` does not have a position on a non-empty attribute, the variable `isEmpty` could remain true, and the function `_burnPassports()` would be triggered to burn this passport even though it contains valid attributes. Moreover, the attributes of the burned passport can still be accessed. ```solidity=246 bool isEmpty = true; // only delete attributes from issuer for (uint256 i = 0; i < governance.getEligibleAttributesLength(); i++) { bytes32 attributeType = governance.eligibleAttributesArray(i); bytes32 attrKey = keccak256(abi.encode(_account, attributeType)); uint256 position = _position[keccak256(abi.encode(attrKey, _msgSender()))]; if (position > 0) { Attribute[] storage attrs = _attributes[attrKey]; // Swap last attribute position with position of attribute to delete before calling pop() Attribute memory attrToDelete = attrs[position-1]; Attribute memory attrToSwap = attrs[attrs.length-1]; _position[keccak256(abi.encode(attrKey, attrToSwap.issuer))] = position; _position[keccak256(abi.encode(attrKey, attrToDelete.issuer))] = 0; attrs[position-1] = attrToSwap; attrs.pop(); if (attrs.length > 0) { isEmpty = false; } } } if (isEmpty){ _burnPassports(_account); } ```
Passport `DID` is the ID of a user, which allows apps to determine if a user owns more than one wallet. The internal function `_validateDid()` will ensure the passport `DID` cannot be changed if trying to set an attribute with a changed `config.did` value. However, passport `DID` can be changed with an issuer signed `config` as the following: ```typescript var config = { attrValues: [didToChange], attrTypes: [ATTRIBUTE_DID], // other parameters } ```
Function `migrate()` can only migrate tokens with ID 1 from the old passport contract.
Function `_setAttributesVerify()` does not require `_config.issuedAt` <= block.timestamp.
Function `migrate()` does not check if the `_issuer` in the former passport contract has the `ISSUER_ROLE` in this contract and allows the `_issuer` to issue a passport to an account.
Function `migrate()` does not check if an account holds a passport in the _newPassport contract, which may lead to data conflicts.
The report names a repository or files. Open the report to see its scope.
Repository and files the report names (14)
1,044 projects reviewed · 1,375 reports · latest May 2025
See CertiK’s auditsSomething 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