Sonic Blaze Testnet

Contract Diff Checker

Contract Name:
PeerToPlayFactory

Contract Source Code:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/**
 * @title PeerToPlayFactory
 * @dev Main Contract For PeerToPlay Smart Accounts. This is also a factory contract, which deploys new PeerToPlay Smart Accounts
 * and serves as a registry for PeerToPlay Smart Accounts.
 */

/**
 * @dev Interface for account functionality in PeerToPlay.
 */
interface AccountInterface {
    /**
     * @dev Returns the version of the account.
     */
    function version() external view returns (uint);

    /**
     * @dev Enables an authority for the account.
     * @param authority The address to be authorized.
     */
    function enable(address authority) external;

    /**
     * @dev Executes multiple function calls within the account.
     * @param _targets The target addresses to call.
     * @param _datas The data (call data) for each target.
     * @param _origin The origin address of the call.
     * @return responses The responses from each call.
     */
    function cast(
        address[] calldata _targets,
        bytes[] calldata _datas,
        address _origin
    ) external payable returns (bytes32[] memory responses);
}

/**
 * @dev Interface for list registry.
 */
interface ListInterface {
    /**
     * @dev Initializes the account in the list.
     * @param _account The account address to initialize.
     */
    function init(address _account) external;
}

/**
 * @title AddressIndex
 * @dev Contract to manage the master address, connectors, and account versions.
 */
contract AddressIndex {
    event LogNewMaster(address indexed master);
    event LogUpdateMaster(address indexed master);
    event LogNewAccount(
        address indexed _newAccount,
        address indexed _connectors
    );

    // New master address.
    address private newMaster;
    // Current master address.
    address public master;
    // List registry address.
    address public list;

    // Connectors mapping for account versions.
    mapping(uint => address) public connectors;
    // Account modules mapping for versions.
    mapping(uint => address) public account;
    // Total version count of account modules.
    uint public versionCount;

    /**
     * @dev Modifier to restrict function access to the master address.
     */
    modifier isMaster() {
        require(msg.sender == master, "not-master");
        _;
    }

    /**
     * @dev Initiates the master address change.
     * @param _newMaster The new master address.
     */
    function changeMaster(address _newMaster) external isMaster {
        require(_newMaster != master, "already-a-master");
        require(_newMaster != address(0), "not-valid-address");
        require(newMaster != _newMaster, "already-a-new-master");
        newMaster = _newMaster;
        emit LogNewMaster(_newMaster);
    }

    /**
     * @dev Finalizes the master address update.
     */
    function updateMaster() external {
        require(newMaster != address(0), "not-valid-address");
        require(msg.sender == newMaster, "not-master");
        master = newMaster;
        newMaster = address(0);
        emit LogUpdateMaster(master);
    }

    /**
     * @dev Adds a new account module.
     * @param _newAccount The new account module address.
     * @param _connectors The connectors registry module address.
     */
    function addNewAccount(
        address _newAccount,
        address _connectors
    ) external isMaster {
        require(_newAccount != address(0), "not-valid-address");
        versionCount++;
        require(
            AccountInterface(_newAccount).version() == versionCount,
            "not-valid-version"
        );
        account[versionCount] = _newAccount;
        if (_connectors != address(0)) connectors[versionCount] = _connectors;
        emit LogNewAccount(_newAccount, _connectors);
    }
}

/**
 * @title CloneFactory
 * @dev Contract to clone other contracts.
 */
contract CloneFactory is AddressIndex {
    /**
     * @dev Creates a new clone of the specified account version.
     * @param version The account module version to clone.
     * @return result The address of the created clone.
     */
    function createClone(uint version) internal returns (address result) {
        bytes20 targetBytes = bytes20(account[version]);
        // solium-disable-next-line security/no-inline-assembly
        assembly {
            let clone := mload(0x40)
            mstore(
                clone,
                0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000
            )
            mstore(add(clone, 0x14), targetBytes)
            mstore(
                add(clone, 0x28),
                0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000
            )
            result := create(0, clone, 0x37)
        }
    }

    /**
     * @dev Checks if a specified address is a clone of a given account version.
     * @param version The account module version.
     * @param query The address to check.
     * @return result Boolean indicating if the address is a clone.
     */
    function isClone(
        uint version,
        address query
    ) external view returns (bool result) {
        bytes20 targetBytes = bytes20(account[version]);
        // solium-disable-next-line security/no-inline-assembly
        assembly {
            let clone := mload(0x40)
            mstore(
                clone,
                0x363d3d373d3d3d363d7300000000000000000000000000000000000000000000
            )
            mstore(add(clone, 0xa), targetBytes)
            mstore(
                add(clone, 0x1e),
                0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000
            )

            let other := add(clone, 0x40)
            extcodecopy(query, other, 0, 0x2d)
            result := and(
                eq(mload(clone), mload(other)),
                eq(mload(add(clone, 0xd)), mload(add(other, 0xd)))
            )
        }
    }
}

/**
 * @title PeerToPlayFactory
 * @dev Main contract for creating and managing PeerToPlay Smart Accounts.
 */
contract PeerToPlayFactory is CloneFactory {
    event LogAccountCreated(
        address sender,
        address indexed owner,
        address indexed account,
        address indexed origin
    );

    /**
     * @dev Creates a PeerToPlay Smart Account and performs a cast operation.
     * @param _owner The owner of the PeerToPlay Smart Account.
     * @param accountVersion The account module version.
     * @param _targets Target addresses for the cast function.
     * @param _datas Data (call data) for each target.
     * @param _origin The origin of the account creation.
     * @return _account The address of the created account.
     */
    function buildWithCast(
        address _owner,
        uint accountVersion,
        address[] calldata _targets,
        bytes[] calldata _datas,
        address _origin
    ) external payable returns (address _account) {
        _account = build(_owner, accountVersion, _origin);
        if (_targets.length > 0)
            AccountInterface(_account).cast{value: msg.value}(
                _targets,
                _datas,
                _origin
            );
    }

    /**
     * @dev Creates a PeerToPlay Smart Account.
     * @param _owner The owner of the PeerToPlay Smart Account.
     * @param accountVersion The account module version.
     * @param _origin The origin of the account creation.
     * @return _account The address of the created account.
     */
    function build(
        address _owner,
        uint accountVersion,
        address _origin
    ) public returns (address _account) {
        require(
            accountVersion != 0 && accountVersion <= versionCount,
            "not-valid-account"
        );
        _account = createClone(accountVersion);
        ListInterface(list).init(_account);
        AccountInterface(_account).enable(_owner);
        emit LogAccountCreated(msg.sender, _owner, _account, _origin);
    }

    /**
     * @dev Sets up initial configuration for the PeerToPlayFactory contract.
     * This function can only be called once.
     * @param _master The master address.
     * @param _list The list registry address.
     * @param _account The initial account module address.
     * @param _connectors The connectors registry module address.
     */
    function setBasics(
        address _master,
        address _list,
        address _account,
        address _connectors
    ) external {
        require(
            master == address(0) &&
                list == address(0) &&
                account[1] == address(0) &&
                connectors[1] == address(0) &&
                versionCount == 0,
            "already-defined"
        );
        master = _master;
        list = _list;
        versionCount++;
        account[versionCount] = _account;
        connectors[versionCount] = _connectors;
    }
}

Please enter a contract address above to load the contract details and source code.

Context size (optional):