← Back to Registry
D-SAFE CERTIFIED

UserBackup.sol Security Audit: The Immutable Ledger

UserBackup.sol Security Audit: The Immutable Ledger

Audit Certificate: BackupStorage Immutable Ledger

Issued by: D-Safe Internal Auditing

This technical briefing certifies the BackupStorage.sol component, operating as the decentralized, persistent memory core for the vue.datapond.earth application. It meticulously archives sequence records—referred to as “patches”—which are highly compressed snapshots capturing user progress and state changes over time.

By publishing the explicit Open Code for BackupStorage.sol on the dsafe.us portal, Pond Enterprise provides absolute verifiability regarding user data retention. This immutable ledger ensures that once a state patch is committed, it cannot be retroactively altered. This technical review certifies the append-only storage mechanisms and the restricted access control layers governing this crucial operational data.

D-CODE Sovereign Licence

Certified SourceCode

The following smart contract source code is published under the D-CODE Licence. This license enforces strict Open Code availability. Unlike Open Source, Open Code means the code is entirely public and auditable for maximum transparency, but it explicitly prohibits unauthorized modifications, derivations, or forks of the certified logic. It requires clear attribution to POND Enterprise.

/**
 * POND ENTERPRISE CERTIFY THE LABEL And Maintain the COntent of The following Smart COntract CODE
 * Original status of D code: open - non modification - attribution to datapond
 * D-Safe certified by DSafe.US
 */
// File: contracts/BackupStorage.sol
pragma solidity ^0.8.24;

import {IBackup} from "./IBackup.sol";
import {ErrorLibrary} from "./ErrorLibrary.sol";

contract BackupStorage is IBackup {
    // Storage
    mapping(uint32 => uint256[]) private _userData;
    // UserId => User Level
    mapping(uint32 => uint8) private _levels;
    // UserId => Level => creationTime
    mapping(uint32 => mapping(uint8 => uint256)) private _levelHistory;
    // userId => Storage Index => string
    mapping(uint32 => mapping(uint32 => string)) private _stringStorage;
    // userId => Storage Indexes that contain strings
    mapping(uint32 => uint256[]) private _stringIndexes;
    // Access control (ScientistStorage-like)
    mapping(address => bool) public _isAuthorized;

    address public admin;

    event AuthorizedAdded(address indexed caller);
    event AuthorizedRemoved(address indexed caller);

    modifier onlyAdmin() {
        require(msg.sender == admin, "not admin");
        _;
    }

    modifier onlyAuthorized() {
        require(_isAuthorized[msg.sender], "not authorized");
        _;
    }

    constructor() {
        admin = msg.sender;
    }

    // Admin API
    function isAuthorized(address caller) external view returns (bool) {
        require(caller != address(0), "zero addr");
        return _isAuthorized[caller];
    }

    function addAuthorized(address caller) external override onlyAdmin {
        require(caller != address(0), "zero addr");
        _isAuthorized[caller] = true;
        emit AuthorizedAdded(caller);
    }

    function removeAuthorized(address caller) external override onlyAdmin {
        _isAuthorized[caller] = false;
        emit AuthorizedRemoved(caller);
    }

    // Writes (authorized)
    function storeBatchActions(
        uint32 userId,
        uint256[] calldata patches,
        uint8 level,
        uint16[] calldata textIndex,
        string[] calldata textData
    ) external override onlyAuthorized {
        uint256 currentLength = _userData[userId].length;
        for (uint32 i = 0; i < patches.length; i++) {
            _userData[userId].push(patches[i]);
        }

        for (uint16 i = 0; i < textIndex.length; i++) {
            uint16 relativePatchIndex = textIndex[i];
            uint256 absoluteIndex = currentLength + relativePatchIndex;
            _stringStorage[userId][uint32(absoluteIndex)] = textData[i];
            _stringIndexes[userId].push(absoluteIndex);
        }

        _levels[userId] = level;
        _levelHistory[userId][level] = block.timestamp;
    }

    function userLevel(uint32 userId) external view override returns (uint8) {
        if (userId <= 0) {
            revert ErrorLibrary.InvalidUserId();
        }
        if (_levels[userId] == 0) {
            return 1;
        }
        return _levels[userId];
    }

    // Reads
    function loadActions(
        uint32 userId
    )
        external
        view
        override
        returns (
            uint256[] memory compressedActions,
            uint256[] memory indexes,
            string[] memory stringIndexes
        )
    {
        uint256[] storage sIndexesStorage = _stringIndexes[userId];
        uint256[] memory sIndexes = new uint256[](sIndexesStorage.length);
        string[] memory sData = new string[](sIndexesStorage.length);

        for (uint256 i = 0; i < sIndexesStorage.length; i++) {
            sIndexes[i] = sIndexesStorage[i];
            sData[i] = _stringStorage[userId][uint32(sIndexesStorage[i])];
        }

        return (_userData[userId], sIndexes, sData);
    }

    function loadActionsSince(
        uint32 userId,
        uint16 index
    )
        external
        view
        override
        returns (
            uint256[] memory compressedActions,
            uint256[] memory indexes,
            string[] memory stringIndexes
        )
    {
        uint256 totalActions = _userData[userId].length;
        if (index >= totalActions) {
            return (new uint256[](0), new uint256[](0), new string[](0));
        }

        uint256 count = totalActions - index;
        uint256[] memory actions = new uint256[](count);
        for (uint256 i = 0; i < count; i++) {
            actions[i] = _userData[userId][index + i];
        }

        uint256[] storage allSIndexes = _stringIndexes[userId];
        uint256 sinceCount = 0;
        for (uint256 i = 0; i < allSIndexes.length; i++) {
            if (allSIndexes[i] >= index) {
                sinceCount++;
            }
        }

        uint256[] memory sIndexes = new uint256[](sinceCount);
        string[] memory sData = new string[](sinceCount);
        uint256 current = 0;
        for (uint256 i = 0; i < allSIndexes.length; i++) {
            if (allSIndexes[i] >= index) {
                sIndexes[current] = allSIndexes[i] - index;
                sData[current] = _stringStorage[userId][uint32(allSIndexes[i])];
                current++;
            }
        }

        return (actions, sIndexes, sData);
    }

    function nbWrites(uint32 userId) external view override returns (uint256) {
        return _userData[userId].length;
    }
}

Build with Indestructible Infrastructure

Our D-SAFE certification ensures your smart contracts meet the highest standards of technical permanence and ethical safety.

Consult with our Architects