账户
0x05...5354
0x05...5354

0x05...5354

$500
此合同的源代码已经过验证!
合同元数据
编译器
0.8.25+commit.b61c2a91
语言
Solidity
合同源代码
文件 1 的 10:Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)

pragma solidity ^0.8.20;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}
合同源代码
文件 2 的 10:CuratorRewardsDistributor.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;

import { Logo } from "../lib/Logo.sol";
import { ICuratorRewardsDistributor } from "../interfaces/ICuratorRewardsDistributor.sol";
import { IPhiRewards } from "../interfaces/IPhiRewards.sol";
import { ICred } from "../interfaces/ICred.sol";
import { SafeTransferLib } from "solady/utils/SafeTransferLib.sol";
import { Ownable2Step } from "@openzeppelin/contracts/access/Ownable2Step.sol";
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";

/// @title CuratorRewardsDistributor
/// @notice Manager of deposits & withdrawals for curator rewards
/// @dev This contract is deployed to same network as the cred contract
contract CuratorRewardsDistributor is Logo, Ownable2Step, ICuratorRewardsDistributor {
    /*//////////////////////////////////////////////////////////////
                                 USING
    //////////////////////////////////////////////////////////////*/
    using SafeTransferLib for address;

    /*//////////////////////////////////////////////////////////////
                                STORAGE
    //////////////////////////////////////////////////////////////*/
    IPhiRewards public phiRewardsContract;
    ICred public credContract;

    uint256 private executeRoyalty = 100;
    uint256 private constant RATIO_BASE = 10_000;
    uint256 private constant MAX_ROYALTY_RANGE = 1000;

    mapping(uint256 credId => uint256 balance) public balanceOf;

    /*//////////////////////////////////////////////////////////////
                              CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/
    constructor(address phiRewardsContract_, address credContract_) payable Ownable(_msgSender()) {
        if (phiRewardsContract_ == address(0) || credContract_ == address(0)) {
            revert InvalidAddressZero();
        }

        phiRewardsContract = IPhiRewards(phiRewardsContract_);
        credContract = ICred(credContract_);
    }

    /*//////////////////////////////////////////////////////////////
                            SETTER FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    function updatePhiRewardsContract(address phiRewardsContract_) external onlyOwner {
        if (phiRewardsContract_ == address(0)) {
            revert InvalidAddressZero();
        }
        phiRewardsContract = IPhiRewards(phiRewardsContract_);
        emit PhiRewardsContractUpdated(phiRewardsContract_);
    }

    function updateCredContract(address credContract_) external onlyOwner {
        if (credContract_ == address(0)) {
            revert InvalidAddressZero();
        }
        credContract = ICred(credContract_);
        emit CredContractUpdated(credContract_);
    }

    function updateExecuteRoyalty(uint256 newExecuteRoyalty_) external onlyOwner {
        if (newExecuteRoyalty_ > MAX_ROYALTY_RANGE) {
            revert InvalidRoyalty(newExecuteRoyalty_);
        }
        executeRoyalty = newExecuteRoyalty_;
        emit ExecuteRoyaltyUpdated(newExecuteRoyalty_);
    }

    /*//////////////////////////////////////////////////////////////
                            UPDATE FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    function deposit(uint256 credId, uint256 amount) external payable {
        if (!credContract.isExist(credId)) revert InvalidCredId();
        if (msg.value != amount) {
            revert InvalidValue(msg.value, amount);
        }
        balanceOf[credId] += amount;
        emit Deposit(_msgSender(), credId, amount);
    }

    function distribute(uint256 credId) external {
        if (!credContract.isExist(credId)) revert InvalidCredId();
        uint256 totalBalance = balanceOf[credId];
        if (totalBalance == 0) {
            revert NoBalanceToDistribute();
        }

        address[] memory distributeAddresses = credContract.getCuratorAddresses(credId, 0, 0);
        uint256 totalNum;

        for (uint256 i = 0; i < distributeAddresses.length; i++) {
            totalNum += credContract.getShareNumber(credId, distributeAddresses[i]);
        }

        if (totalNum == 0) {
            revert NoSharesToDistribute();
        }

        uint256[] memory amounts = new uint256[](distributeAddresses.length);
        bytes4[] memory reasons = new bytes4[](distributeAddresses.length);

        uint256 executefee = (totalBalance * executeRoyalty) / RATIO_BASE;
        uint256 distributeAmount = totalBalance - executefee;

        // actualDistributeAmount is used to avoid rounding errors
        // amount[0] = 333 333 333 333 333 333
        // amount[1] = 333 333 333 333 333 333
        // amount[2] = 333 333 333 333 333 333
        uint256 actualDistributeAmount = 0;
        for (uint256 i = 0; i < distributeAddresses.length; i++) {
            address user = distributeAddresses[i];

            uint256 userAmounts = credContract.getShareNumber(credId, user);
            uint256 userRewards = (distributeAmount * userAmounts) / totalNum;

            if (userRewards > 0) {
                amounts[i] = userRewards;
                actualDistributeAmount += userRewards;
            }
        }

        balanceOf[credId] -= totalBalance;

        _msgSender().safeTransferETH(executefee + distributeAmount - actualDistributeAmount);

        //slither-disable-next-line arbitrary-send-eth
        phiRewardsContract.depositBatch{ value: actualDistributeAmount }(
            distributeAddresses, amounts, reasons, "deposit from curator rewards distributor"
        );

        emit RewardsDistributed(
            credId, _msgSender(), executefee + distributeAmount - actualDistributeAmount, distributeAmount, totalBalance
        );
    }
}
合同源代码
文件 3 的 10:ICred.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;

interface ICred {
    /*//////////////////////////////////////////////////////////////
                                 ERRORS
    //////////////////////////////////////////////////////////////*/
    error InvalidAddressZero();
    error InsufficientPayment();
    error InsufficientShares();
    error AddressNotSigned();
    error InvalidCredType();
    error InvalidVerificationType();
    error UnauthorizedCaller();
    error InvalidArrayLength();
    error InsufficientBatchPayment();
    error Reentrancy();
    error InvalidPaginationParameters();
    error MaxSupplyReached();
    error SignatureExpired();
    error InvalidAmount();
    error UnauthorizedCurve();
    error InvalidMerkleRoot();
    error EmptyBatchOperation();
    error DuplicateCredId();
    error InvalidRoyaltyRange();
    error InvalidCredId();
    error EmptyArray();
    error IndexOutofBounds();
    error WrongCredId();
    error ShareLockPeriodNotPassed(uint256 currentTimestamp, uint256 unlockTimestamp);
    error PriceExceedsLimit();
    error PriceBelowLimit();
    error InvalidChainId();
    error InvalidNonce();
    error protocolFeePercentTooHigh();

    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/
    /// @notice Emitted phi rewards address is set.
    event PhiRewardsAddressSet(address phiRewardsAddress);

    /// @notice Emitted when the protocol signer address is set.
    event PhiSignerAddressSet(address phiSignerAddress);

    /// @notice
    event CreatorRoyalty(address indexed creator, uint256 indexed credId, bool isBuy, uint256 Amount);

    /// @notice Emitted when a trade occurs.
    /// @param curator The address of the curator.
    /// @param credId The ID of the cred.
    /// @param isBuy Whether the trade is a buy (true) or sell (false).
    /// @param amount The amount of shares traded.
    /// @param ethAmount The amount of ETH involved in the trade.
    /// @param protocolEthAmount The amount of ETH paid as protocol fee.
    /// @param supply The new supply of the cred after the trade.
    event Trade(
        address indexed curator,
        uint256 indexed credId,
        bool isBuy,
        uint256 amount,
        uint256 ethAmount,
        uint256 protocolEthAmount,
        uint256 supply
    );

    /// @notice Emitted when a new cred is created.
    /// @param creator The address of the cred creator.
    /// @param credId The ID of the new cred.
    /// @param credURL The URL of the cred data.
    /// @param credType The type of the cred.
    /// @param verificationType The type of verification
    /// @param amount The initial amount share buy of the cred.
    event CredCreated(
        address indexed creator,
        uint256 credId,
        string credURL,
        string credType,
        string verificationType,
        uint256 amount
    );

    /// @notice Emitted when the URL of a cred is updated.
    /// @param creator The creator of the cred.
    /// @param credId The ID of the cred.
    /// @param credURL The new URL of the cred data.
    event CredUpdated(address indexed creator, uint256 credId, string credURL);

    /// @notice Emitted when an address is added to the whitelist.
    /// @param sender The address that added the new address to the whitelist.
    /// @param whitelistedAddress The address that was added to the whitelist.
    event AddedToWhitelist(address indexed sender, address indexed whitelistedAddress);

    /// @notice Emitted when an address is removed from the whitelist.
    /// @param sender The address that removed the address from the whitelist.
    /// @param unwhitelistedAddress The address that was removed from the whitelist.
    event RemovedFromWhitelist(address indexed sender, address indexed unwhitelistedAddress);

    /// @notice Emitted when the protocol fee percentage is changed.
    /// @param changer The address that changed the protocol fee percentage.
    /// @param newFee The new protocol fee percentage.
    event ProtocolFeePercentChanged(address changer, uint256 newFee);

    /// @notice Emitted when the protocol fee destination is changed.
    /// @param changer The address that changed the protocol fee destination.
    /// @param newDestination The new protocol fee destination.
    event ProtocolFeeDestinationChanged(address changer, address newDestination);

    /// @notice Emitted when a Merkle tree is set up for a cred.
    /// @param sender The address that set up the Merkle tree.
    /// @param credId The ID of the cred.
    /// @param root The root of the Merkle tree.
    event MerkleTreeSetUp(address sender, uint256 credId, bytes32 root);

    /*//////////////////////////////////////////////////////////////
                                 STRUCTS
    //////////////////////////////////////////////////////////////*/
    struct CreateCredData {
        uint256 expiresIn;
        uint256 nonce;
        address executor;
        uint256 chainId;
        address bondingCurve;
        string credURL;
        string credType;
        string verificationType;
        bytes32 merkleRoot;
    }

    struct UpdateCredData {
        uint256 expiresIn;
        uint256 nonce;
        uint256 chainId;
        uint256 credId;
        string credURL;
    }

    /// @dev Represents a cred.
    struct PhiCred {
        address creator;
        uint256 currentSupply;
        string credURL; // description in arweave
        string credType;
        string verificationType;
        address bondingCurve;
        uint16 buyShareRoyalty;
        uint16 sellShareRoyalty;
        uint40 createdAt;
        uint40 updatedAt;
        uint256 latestActiveTimestamp;
    }

    /// @dev Represents a user's curation of a cred.
    struct CuratorData {
        address curator;
        uint256 shareAmount;
    }

    /*//////////////////////////////////////////////////////////////
                            EXTERNAL FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    /// @notice buy a cred.
    /// @param credId The ID of the cred.
    /// @param amount The amount to buy.
    function buyShareCred(uint256 credId, uint256 amount, uint256 maxPrice) external payable;

    /// @notice Sell a cred.
    /// @param credId The ID of the cred.
    /// @param amount The amount to sell.
    function sellShareCred(uint256 credId, uint256 amount, uint256 minPrice) external;

    // Read functions
    /// @notice Gets the creator of a cred.
    /// @param credId The ID of the cred.
    /// @return The address of the cred creator.
    function getCredCreator(uint256 credId) external view returns (address);

    /// @notice Gets information about a cred.
    /// @param credId The ID of the cred.
    /// @return The cred information.
    function credInfo(uint256 credId) external view returns (PhiCred memory);

    /// @param credId The ID of the cred.
    /// @param curator The address to check.
    /// @return The number of share the address has for the cred.
    function getShareNumber(uint256 credId, address curator) external view returns (uint256);
    function createCred(
        address creator,
        bytes calldata signedData,
        bytes calldata signature,
        uint16 buyShareRoyalty,
        uint16 sellShareRoyalty,
        uint256 amount
    )
        external
        payable;

    /// @param credId The ID of the cred.
    /// @param start The starting index of the range.
    /// @param stop The ending index of the range.
    /// @return The addresses that have the cred.
    function getCuratorAddresses(
        uint256 credId,
        uint256 start,
        uint256 stop
    )
        external
        view
        returns (address[] memory);

    /// @notice Gets the buy price of a cred for a given amount.
    /// @param credId The ID of the cred.
    /// @param amount The amount to buy.
    /// @return The buy price.
    function getCredBuyPrice(uint256 credId, uint256 amount) external view returns (uint256);

    /// @notice Gets the buy price of a cred with fee for a given amount.
    /// @param credId The ID of the cred.
    /// @param amount The amount to buy.
    /// @return The buy price with fee.
    function getCredBuyPriceWithFee(uint256 credId, uint256 amount) external view returns (uint256);

    /// @notice Gets the sell price of a cred for a given amount.
    /// @param credId The ID of the cred.
    /// @param amount The amount to sell.
    /// @return The sell price.
    function getCredSellPrice(uint256 credId, uint256 amount) external view returns (uint256);

    /// @notice Gets the sell price of a cred with fee for a given amount.
    /// @param credId The ID of the cred.
    /// @param amount The amount to sell.
    /// @return The sell price with fee.
    function getCredSellPriceWithFee(uint256 credId, uint256 amount) external view returns (uint256);

    /// @notice Gets the total buy price for a batch of creds and amounts.
    /// @param credIds The IDs of the creds.
    /// @param amounts The amounts corresponding to each cred.
    /// @return The total buy price for the batch.
    function getBatchBuyPrice(uint256[] calldata credIds, uint256[] calldata amounts) external view returns (uint256);

    /// @notice Gets the total sell price for a batch of creds and amounts.
    /// @param credIds The IDs of the creds.
    /// @param amounts The amounts corresponding to each cred.
    /// @return The total sell price for the batch.
    function getBatchSellPrice(
        uint256[] calldata credIds,
        uint256[] calldata amounts
    )
        external
        view
        returns (uint256);

    /// @notice Checks if a cred exists.
    /// @param credId The ID of the cred.
    /// @return Whether the cred exists.
    function isExist(uint256 credId) external view returns (bool);

    /// @param credId The ID of the cred.
    /// @param curator The address to check.
    /// @return Whether the address has the cred.
    function isShareHolder(uint256 credId, address curator) external view returns (bool);

    /// @notice Gets the protocol fee percentage.
    /// @return The protocol fee percentage.
    function protocolFeePercent() external view returns (uint256);

    /// @notice Gets the protocol fee destination.
    /// @return The protocol fee destination.
    function protocolFeeDestination() external view returns (address);

    /// @notice Gets the creator royalty percentages.
    /// @param credId The ID of the cred.
    /// @return The buy and sell royalty.
    function getCreatorRoyalty(uint256 credId) external view returns (uint16, uint16);
}
合同源代码
文件 4 的 10:ICuratorRewardsDistributor.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;

interface ICuratorRewardsDistributor {
    /*//////////////////////////////////////////////////////////////
                                 ERRORS
    //////////////////////////////////////////////////////////////*/
    error InvalidAddressZero();
    error NoBalanceToDistribute();
    error NoSharesToDistribute();
    error InvalidTokenAmounts(uint256 gotAmounts);
    error InvalidValue(uint256 gotValue, uint256 expectedValue);
    error UnauthorizedCaller(address caller);
    error Reentrancy();
    error InvalidRoyalty(uint256 royalty);
    error InvalidCredId();

    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/
    event Deposit(address sender, uint256 indexed credId, uint256 amount);
    event RewardsDistributed(
        uint256 indexed credId, address indexed sender, uint256 executefee, uint256 distributeAmount, uint256 total
    );
    event CredContractUpdated(address newCredContract);
    event PhiRewardsContractUpdated(address newPhiRewardsContract);
    event ExecuteRoyaltyUpdated(uint256 newRoyalty);

    /*//////////////////////////////////////////////////////////////
                            EXTERNAL FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    /// @notice Gets the balance of the cred.
    function balanceOf(uint256 credId) external view returns (uint256);
    /// @notice Deposits an amount of ETH into the contract.
    /// @param credId The ID of the cred.
    /// @param amount The amount of ETH to deposit.
    function deposit(uint256 credId, uint256 amount) external payable;
    /// @notice Distributes the rewards to the addresses.
    /// @param credId The ID of the cred.
    function distribute(uint256 credId) external;
}
合同源代码
文件 5 的 10:IPhiRewards.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;

import { IRewards } from "./IRewards.sol";

interface IPhiRewards is IRewards {
    /*//////////////////////////////////////////////////////////////
                                 ERRORS
    //////////////////////////////////////////////////////////////*/
    error ContractNotCreatedByFactory();
    error PhiFactoryNotSet();

    /*//////////////////////////////////////////////////////////////
                                EVENTS
    //////////////////////////////////////////////////////////////*/
    event PhiFactoryUpdated(address newPhiFactory);
    event ArtistRewardUpdated(uint256 artistReward);
    event ReferralRewardUpdated(uint256 referralReward);
    event VerifierRewardUpdated(uint256 verifierReward);
    event CuratorRewardUpdated(uint256 curateReward);
    event CuratorRewardsDistributorUpdated(address curatorRewardsDistributor);
    event RewardsDeposit(
        address minter, address indexed receiver, address indexed referral, address indexed verifier, bytes rewardsData
    );
    event NotChainSyncDeposit(uint256 artId, address verifier, uint256 curateTotalReward);

    /*//////////////////////////////////////////////////////////////
                            EXTERNAL FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    /// @notice Updates the curator rewards distributor address
    /// @param curatorRewardsDistributor_ The new curator rewards distributor address
    function updateCuratorRewardsDistributor(address curatorRewardsDistributor_) external;

    function setPhiFactory(address phiFactory_) external;

    /// @notice Handles rewards and gets the value sent
    /// @param artId_ The art ID
    /// @param credId_ The credential ID
    /// @param quantity_ The quantity
    /// @param mintFee_ The minting fee
    /// @param addressesData_ The encoded addresses data (minter, receiver, referral, verifier)
    /// @param chainSync_ Whether to sync with the chain or not
    function handleRewardsAndGetValueSent(
        uint256 artId_,
        uint256 credId_,
        uint256 quantity_,
        uint256 mintFee_,
        bytes calldata addressesData_,
        bool chainSync_
    )
        external
        payable;

    /// @notice Computes the minting reward
    /// @param quantity_ The quantity
    /// @param mintFee_ The minting fee
    /// @return The computed minting reward
    function computeMintReward(uint256 quantity_, uint256 mintFee_) external view returns (uint256);
}
合同源代码
文件 6 的 10:IRewards.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;

/// @title IRewards
/// @notice The interface for deposits and withdrawals
interface IRewards {
    /*//////////////////////////////////////////////////////////////
                                 ERRORS
    //////////////////////////////////////////////////////////////*/
    /// @notice Thrown when trying to send to the zero address
    error InvalidAddressZero();
    /// @notice Thrown when function argument array lengths mismatch
    error ArrayLengthMismatch();
    /// @notice Thrown when an invalid deposit is made
    error InvalidDeposit();
    /// @notice Thrown when an invalid signature is provided for a deposit
    error InvalidSignature();
    /// @notice Thrown when an invalid amount is provided
    error InvalidAmount();
    /// @notice signature has expired
    error DeadlineExpired();

    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/
    /// @notice Emitted when a deposit is made
    /// @param from The address making the deposit
    /// @param to The address receiving the deposit
    /// @param reason Optional bytes4 reason for indexing
    /// @param amount Amount of the deposit
    /// @param comment Optional user comment
    event Deposit(address indexed from, address indexed to, bytes4 indexed reason, uint256 amount, string comment);

    /// @notice Emitted when a withdrawal is made
    /// @param from The address making the withdrawal
    /// @param to The address receiving the withdrawal
    /// @param amount Amount of the withdrawal
    event Withdraw(address indexed from, address indexed to, uint256 amount);

    /*//////////////////////////////////////////////////////////////
                             EXTERNAL FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    /// @notice Deposits ETH for a recipient, with an optional comment
    /// @param to Address to deposit to
    /// @param reason System reason for deposit (used for indexing)
    /// @param comment Optional comment as reason for deposit
    function deposit(address to, bytes4 reason, string calldata comment) external payable;

    /// @notice Deposits ETH for multiple recipients, with an optional comment
    /// @param recipients Recipients to send the amounts to, array aligns with amounts
    /// @param amounts Amounts to send to each recipient, array aligns with recipients
    /// @param reasons Optional bytes4 hashes for indexing
    /// @param comment Optional comment to include with deposit
    function depositBatch(
        address[] calldata recipients,
        uint256[] calldata amounts,
        bytes4[] calldata reasons,
        string calldata comment
    )
        external
        payable;

    /// @notice Withdraws protocol rewards
    /// @param to Address to withdraw to
    /// @param amount Amount to withdraw
    function withdraw(address to, uint256 amount) external;

    /// @notice Withdraws rewards on behalf of an address
    /// @param to Address to withdraw for
    /// @param amount Amount to withdraw (0 for total balance)
    function withdrawFor(address to, uint256 amount) external;

    /// @notice Executes a withdrawal of protocol rewards via signature
    /// @param from Address to withdraw from
    /// @param to Address to withdraw to
    /// @param amount Amount to withdraw
    /// @param deadline Deadline for the signature to be valid
    /// @param sig Signature for the withdrawal
    function withdrawWithSig(address from, address to, uint256 amount, uint256 deadline, bytes calldata sig) external;

    /*//////////////////////////////////////////////////////////////
                             VIEW FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    /// @notice Returns the total amount of ETH held in the contract
    function totalSupply() external view returns (uint256);
}
合同源代码
文件 7 的 10:Logo.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;

/*
                  ____    ____
                 /\___\  /\___\
       ________/ /   /_ \/___/
      /\_______\/   /__\___\
     / /       /       /   /
    / /   /   /   /   /   /
   / /   /___/___/___/___/
  / /   /
 \/___/

*/

interface Logo {
// This is a simple Logo image
}
合同源代码
文件 8 的 10:Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)

pragma solidity ^0.8.20;

import {Context} from "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * The initial owner is set to the address provided by the deployer. This can
 * later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    /**
     * @dev The caller account is not authorized to perform an operation.
     */
    error OwnableUnauthorizedAccount(address account);

    /**
     * @dev The owner is not a valid owner account. (eg. `address(0)`)
     */
    error OwnableInvalidOwner(address owner);

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
     */
    constructor(address initialOwner) {
        if (initialOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(initialOwner);
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        if (owner() != _msgSender()) {
            revert OwnableUnauthorizedAccount(_msgSender());
        }
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        if (newOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}
合同源代码
文件 9 的 10:Ownable2Step.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable2Step.sol)

pragma solidity ^0.8.20;

import {Ownable} from "./Ownable.sol";

/**
 * @dev Contract module which provides access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * The initial owner is specified at deployment time in the constructor for `Ownable`. This
 * can later be changed with {transferOwnership} and {acceptOwnership}.
 *
 * This module is used through inheritance. It will make available all functions
 * from parent (Ownable).
 */
abstract contract Ownable2Step is Ownable {
    address private _pendingOwner;

    event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Returns the address of the pending owner.
     */
    function pendingOwner() public view virtual returns (address) {
        return _pendingOwner;
    }

    /**
     * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual override onlyOwner {
        _pendingOwner = newOwner;
        emit OwnershipTransferStarted(owner(), newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual override {
        delete _pendingOwner;
        super._transferOwnership(newOwner);
    }

    /**
     * @dev The new owner accepts the ownership transfer.
     */
    function acceptOwnership() public virtual {
        address sender = _msgSender();
        if (pendingOwner() != sender) {
            revert OwnableUnauthorizedAccount(sender);
        }
        _transferOwnership(sender);
    }
}
合同源代码
文件 10 的 10:SafeTransferLib.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeTransferLib.sol)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)
///
/// @dev Note:
/// - For ETH transfers, please use `forceSafeTransferETH` for DoS protection.
/// - For ERC20s, this implementation won't check that a token has code,
///   responsibility is delegated to the caller.
library SafeTransferLib {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                       CUSTOM ERRORS                        */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The ETH transfer has failed.
    error ETHTransferFailed();

    /// @dev The ERC20 `transferFrom` has failed.
    error TransferFromFailed();

    /// @dev The ERC20 `transfer` has failed.
    error TransferFailed();

    /// @dev The ERC20 `approve` has failed.
    error ApproveFailed();

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                         CONSTANTS                          */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Suggested gas stipend for contract receiving ETH that disallows any storage writes.
    uint256 internal constant GAS_STIPEND_NO_STORAGE_WRITES = 2300;

    /// @dev Suggested gas stipend for contract receiving ETH to perform a few
    /// storage reads and writes, but low enough to prevent griefing.
    uint256 internal constant GAS_STIPEND_NO_GRIEF = 100000;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                       ETH OPERATIONS                       */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    // If the ETH transfer MUST succeed with a reasonable gas budget, use the force variants.
    //
    // The regular variants:
    // - Forwards all remaining gas to the target.
    // - Reverts if the target reverts.
    // - Reverts if the current contract has insufficient balance.
    //
    // The force variants:
    // - Forwards with an optional gas stipend
    //   (defaults to `GAS_STIPEND_NO_GRIEF`, which is sufficient for most cases).
    // - If the target reverts, or if the gas stipend is exhausted,
    //   creates a temporary contract to force send the ETH via `SELFDESTRUCT`.
    //   Future compatible with `SENDALL`: https://eips.ethereum.org/EIPS/eip-4758.
    // - Reverts if the current contract has insufficient balance.
    //
    // The try variants:
    // - Forwards with a mandatory gas stipend.
    // - Instead of reverting, returns whether the transfer succeeded.

    /// @dev Sends `amount` (in wei) ETH to `to`.
    function safeTransferETH(address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            if iszero(call(gas(), to, amount, codesize(), 0x00, codesize(), 0x00)) {
                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
                revert(0x1c, 0x04)
            }
        }
    }

    /// @dev Sends all the ETH in the current contract to `to`.
    function safeTransferAllETH(address to) internal {
        /// @solidity memory-safe-assembly
        assembly {
            // Transfer all the ETH and check if it succeeded or not.
            if iszero(call(gas(), to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {
                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
                revert(0x1c, 0x04)
            }
        }
    }

    /// @dev Force sends `amount` (in wei) ETH to `to`, with a `gasStipend`.
    function forceSafeTransferETH(address to, uint256 amount, uint256 gasStipend) internal {
        /// @solidity memory-safe-assembly
        assembly {
            if lt(selfbalance(), amount) {
                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
                revert(0x1c, 0x04)
            }
            if iszero(call(gasStipend, to, amount, codesize(), 0x00, codesize(), 0x00)) {
                mstore(0x00, to) // Store the address in scratch space.
                mstore8(0x0b, 0x73) // Opcode `PUSH20`.
                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
                if iszero(create(amount, 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.
            }
        }
    }

    /// @dev Force sends all the ETH in the current contract to `to`, with a `gasStipend`.
    function forceSafeTransferAllETH(address to, uint256 gasStipend) internal {
        /// @solidity memory-safe-assembly
        assembly {
            if iszero(call(gasStipend, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {
                mstore(0x00, to) // Store the address in scratch space.
                mstore8(0x0b, 0x73) // Opcode `PUSH20`.
                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
                if iszero(create(selfbalance(), 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.
            }
        }
    }

    /// @dev Force sends `amount` (in wei) ETH to `to`, with `GAS_STIPEND_NO_GRIEF`.
    function forceSafeTransferETH(address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            if lt(selfbalance(), amount) {
                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
                revert(0x1c, 0x04)
            }
            if iszero(call(GAS_STIPEND_NO_GRIEF, to, amount, codesize(), 0x00, codesize(), 0x00)) {
                mstore(0x00, to) // Store the address in scratch space.
                mstore8(0x0b, 0x73) // Opcode `PUSH20`.
                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
                if iszero(create(amount, 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.
            }
        }
    }

    /// @dev Force sends all the ETH in the current contract to `to`, with `GAS_STIPEND_NO_GRIEF`.
    function forceSafeTransferAllETH(address to) internal {
        /// @solidity memory-safe-assembly
        assembly {
            // forgefmt: disable-next-item
            if iszero(call(GAS_STIPEND_NO_GRIEF, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {
                mstore(0x00, to) // Store the address in scratch space.
                mstore8(0x0b, 0x73) // Opcode `PUSH20`.
                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
                if iszero(create(selfbalance(), 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.
            }
        }
    }

    /// @dev Sends `amount` (in wei) ETH to `to`, with a `gasStipend`.
    function trySafeTransferETH(address to, uint256 amount, uint256 gasStipend)
        internal
        returns (bool success)
    {
        /// @solidity memory-safe-assembly
        assembly {
            success := call(gasStipend, to, amount, codesize(), 0x00, codesize(), 0x00)
        }
    }

    /// @dev Sends all the ETH in the current contract to `to`, with a `gasStipend`.
    function trySafeTransferAllETH(address to, uint256 gasStipend)
        internal
        returns (bool success)
    {
        /// @solidity memory-safe-assembly
        assembly {
            success := call(gasStipend, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                      ERC20 OPERATIONS                      */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Sends `amount` of ERC20 `token` from `from` to `to`.
    /// Reverts upon failure.
    ///
    /// The `from` account must have at least `amount` approved for
    /// the current contract to manage.
    function safeTransferFrom(address token, address from, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40) // Cache the free memory pointer.
            mstore(0x60, amount) // Store the `amount` argument.
            mstore(0x40, to) // Store the `to` argument.
            mstore(0x2c, shl(96, from)) // Store the `from` argument.
            mstore(0x0c, 0x23b872dd000000000000000000000000) // `transferFrom(address,address,uint256)`.
            // Perform the transfer, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
                )
            ) {
                mstore(0x00, 0x7939f424) // `TransferFromFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x60, 0) // Restore the zero slot to zero.
            mstore(0x40, m) // Restore the free memory pointer.
        }
    }

    /// @dev Sends all of ERC20 `token` from `from` to `to`.
    /// Reverts upon failure.
    ///
    /// The `from` account must have their entire balance approved for
    /// the current contract to manage.
    function safeTransferAllFrom(address token, address from, address to)
        internal
        returns (uint256 amount)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40) // Cache the free memory pointer.
            mstore(0x40, to) // Store the `to` argument.
            mstore(0x2c, shl(96, from)) // Store the `from` argument.
            mstore(0x0c, 0x70a08231000000000000000000000000) // `balanceOf(address)`.
            // Read the balance, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    gt(returndatasize(), 0x1f), // At least 32 bytes returned.
                    staticcall(gas(), token, 0x1c, 0x24, 0x60, 0x20)
                )
            ) {
                mstore(0x00, 0x7939f424) // `TransferFromFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x00, 0x23b872dd) // `transferFrom(address,address,uint256)`.
            amount := mload(0x60) // The `amount` is already at 0x60. We'll need to return it.
            // Perform the transfer, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
                )
            ) {
                mstore(0x00, 0x7939f424) // `TransferFromFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x60, 0) // Restore the zero slot to zero.
            mstore(0x40, m) // Restore the free memory pointer.
        }
    }

    /// @dev Sends `amount` of ERC20 `token` from the current contract to `to`.
    /// Reverts upon failure.
    function safeTransfer(address token, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x14, to) // Store the `to` argument.
            mstore(0x34, amount) // Store the `amount` argument.
            mstore(0x00, 0xa9059cbb000000000000000000000000) // `transfer(address,uint256)`.
            // Perform the transfer, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
                )
            ) {
                mstore(0x00, 0x90b8ec18) // `TransferFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
        }
    }

    /// @dev Sends all of ERC20 `token` from the current contract to `to`.
    /// Reverts upon failure.
    function safeTransferAll(address token, address to) internal returns (uint256 amount) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, 0x70a08231) // Store the function selector of `balanceOf(address)`.
            mstore(0x20, address()) // Store the address of the current contract.
            // Read the balance, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    gt(returndatasize(), 0x1f), // At least 32 bytes returned.
                    staticcall(gas(), token, 0x1c, 0x24, 0x34, 0x20)
                )
            ) {
                mstore(0x00, 0x90b8ec18) // `TransferFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x14, to) // Store the `to` argument.
            amount := mload(0x34) // The `amount` is already at 0x34. We'll need to return it.
            mstore(0x00, 0xa9059cbb000000000000000000000000) // `transfer(address,uint256)`.
            // Perform the transfer, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
                )
            ) {
                mstore(0x00, 0x90b8ec18) // `TransferFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
        }
    }

    /// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract.
    /// Reverts upon failure.
    function safeApprove(address token, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x14, to) // Store the `to` argument.
            mstore(0x34, amount) // Store the `amount` argument.
            mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.
            // Perform the approval, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
                )
            ) {
                mstore(0x00, 0x3e3f8f73) // `ApproveFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
        }
    }

    /// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract.
    /// If the initial attempt to approve fails, attempts to reset the approved amount to zero,
    /// then retries the approval again (some tokens, e.g. USDT, requires this).
    /// Reverts upon failure.
    function safeApproveWithRetry(address token, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x14, to) // Store the `to` argument.
            mstore(0x34, amount) // Store the `amount` argument.
            mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.
            // Perform the approval, retrying upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
                )
            ) {
                mstore(0x34, 0) // Store 0 for the `amount`.
                mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.
                pop(call(gas(), token, 0, 0x10, 0x44, codesize(), 0x00)) // Reset the approval.
                mstore(0x34, amount) // Store back the original `amount`.
                // Retry the approval, reverting upon failure.
                if iszero(
                    and(
                        or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                        call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
                    )
                ) {
                    mstore(0x00, 0x3e3f8f73) // `ApproveFailed()`.
                    revert(0x1c, 0x04)
                }
            }
            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
        }
    }

    /// @dev Returns the amount of ERC20 `token` owned by `account`.
    /// Returns zero if the `token` does not exist.
    function balanceOf(address token, address account) internal view returns (uint256 amount) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x14, account) // Store the `account` argument.
            mstore(0x00, 0x70a08231000000000000000000000000) // `balanceOf(address)`.
            amount :=
                mul(
                    mload(0x20),
                    and( // The arguments of `and` are evaluated from right to left.
                        gt(returndatasize(), 0x1f), // At least 32 bytes returned.
                        staticcall(gas(), token, 0x10, 0x24, 0x20, 0x20)
                    )
                )
        }
    }
}
设置
{
  "compilationTarget": {
    "src/reward/CuratorRewardsDistributor.sol": "CuratorRewardsDistributor"
  },
  "evmVersion": "paris",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "none"
  },
  "optimizer": {
    "enabled": true,
    "runs": 1000
  },
  "remappings": [
    ":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
    ":@openzeppelin/contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/",
    ":@prb/test/=node_modules/@prb/test/",
    ":ds-test/=lib/solady/lib/ds-test/src/",
    ":erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
    ":forge-std/=lib/forge-std/src/",
    ":foundry-devops/=lib/foundry-devops/src/",
    ":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
    ":openzeppelin-contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/",
    ":openzeppelin-foundry-upgrades/=lib/openzeppelin-foundry-upgrades/src/",
    ":solady/=lib/solady/src/",
    ":solidity-stringutils/=lib/openzeppelin-foundry-upgrades/lib/solidity-stringutils/"
  ]
}
ABI
[{"inputs":[{"internalType":"address","name":"phiRewardsContract_","type":"address"},{"internalType":"address","name":"credContract_","type":"address"}],"stateMutability":"payable","type":"constructor"},{"inputs":[],"name":"InvalidAddressZero","type":"error"},{"inputs":[],"name":"InvalidCredId","type":"error"},{"inputs":[{"internalType":"uint256","name":"royalty","type":"uint256"}],"name":"InvalidRoyalty","type":"error"},{"inputs":[{"internalType":"uint256","name":"gotAmounts","type":"uint256"}],"name":"InvalidTokenAmounts","type":"error"},{"inputs":[{"internalType":"uint256","name":"gotValue","type":"uint256"},{"internalType":"uint256","name":"expectedValue","type":"uint256"}],"name":"InvalidValue","type":"error"},{"inputs":[],"name":"NoBalanceToDistribute","type":"error"},{"inputs":[],"name":"NoSharesToDistribute","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"Reentrancy","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"UnauthorizedCaller","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newCredContract","type":"address"}],"name":"CredContractUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"uint256","name":"credId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newRoyalty","type":"uint256"}],"name":"ExecuteRoyaltyUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newPhiRewardsContract","type":"address"}],"name":"PhiRewardsContractUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"credId","type":"uint256"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"executefee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"distributeAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"total","type":"uint256"}],"name":"RewardsDistributed","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"credId","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"credContract","outputs":[{"internalType":"contract ICred","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"credId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"credId","type":"uint256"}],"name":"distribute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"phiRewardsContract","outputs":[{"internalType":"contract IPhiRewards","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"credContract_","type":"address"}],"name":"updateCredContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newExecuteRoyalty_","type":"uint256"}],"name":"updateExecuteRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"phiRewardsContract_","type":"address"}],"name":"updatePhiRewardsContract","outputs":[],"stateMutability":"nonpayable","type":"function"}]