Cryo Explorer Ethereum Mainnet

Address Contract Verified

Address 0xe32029E102892a458db21DEd60F0D37EdBBe5cF4
Balance 0 ETH
Nonce 1
Code Size 8508 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

8508 bytes
0x608060405260043610610073575f3560e01c80638da5cb5b1161004d5780638da5cb5b1461011d578063b2118a8d14610147578063d0de1ddc1461016f578063f2fde38b14610197576100b3565b8063469f0ab5146100b7578063690d8320146100df578063715018a614610107576100b3565b366100b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100aa90611116565b60405180910390fd5b5f5ffd5b3480156100c2575f5ffd5b506100dd60048036038101906100d891906113e2565b6101bf565b005b3480156100ea575f5ffd5b5061010560048036038101906101009190611493565b6101d5565b005b348015610112575f5ffd5b5061011b61038c565b005b348015610128575f5ffd5b5061013161039f565b60405161013e91906114cd565b60405180910390f35b348015610152575f5ffd5b5061016d600480360381019061016891906114e6565b6103c7565b005b34801561017a575f5ffd5b5061019560048036038101906101909190611536565b6106da565b005b3480156101a2575f5ffd5b506101bd60048036038101906101b89190611574565b610af5565b005b6101c7610b79565b6101d18282610c00565b5050565b6101dd610b79565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361024b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610242906115e9565b60405180910390fd5b5f4790505f8111610291576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161028890611651565b60405180910390fd5b5f8273ffffffffffffffffffffffffffffffffffffffff16826040516102b69061169c565b5f6040518083038185875af1925050503d805f81146102f0576040519150601f19603f3d011682016040523d82523d5f602084013e6102f5565b606091505b5050905080610339576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610330906116fa565b60405180910390fd5b8273ffffffffffffffffffffffffffffffffffffffff167f6148672a948a12b8e0bf92a9338349b9ac890fad62a234abaf0a4da99f62cfcc8360405161037f9190611727565b60405180910390a2505050565b610394610b79565b61039d5f610e63565b565b5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6103cf610b79565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361043d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104349061178a565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036104ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104a2906117f2565b60405180910390fd5b5f81116104ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104e49061185a565b60405180910390fd5b5f8390505f8173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161052b91906114cd565b602060405180830381865afa158015610546573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061056a919061188c565b9050808311156105af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105a690611927565b60405180910390fd5b5f8273ffffffffffffffffffffffffffffffffffffffff1663a9059cbb86866040518363ffffffff1660e01b81526004016105eb929190611945565b6020604051808303815f875af1158015610607573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061062b91906119a1565b90508061066d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066490611a16565b60405180910390fd5b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167f4ef96419716b45f517dc240344424ade2aa3be63eea169e6d947fdb6c2ea31ac866040516106ca9190611727565b60405180910390a3505050505050565b6106e2610f26565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610750576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107479061178a565b60405180910390fd5b5f8111610792576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107899061185a565b60405180910390fd5b5f8290505f8173ffffffffffffffffffffffffffffffffffffffff166323b872dd6107bb610f73565b30866040518463ffffffff1660e01b81526004016107db93929190611a34565b6020604051808303815f875af11580156107f7573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061081b91906119a1565b90508061085d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161085490611ad9565b60405180910390fd5b5f60028054806020026020016040519081016040528092919081815260200182805480156108dd57602002820191905f5260205f20905b815f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610894575b505050505090505f600380548060200260200160405190810160405280929190818152602001828054801561092f57602002820191905f5260205f20905b81548152602001906001019080831161091b575b505050505090505f5f90505b8251811015610a74575f83828151811061095857610957611af7565b5b602002602001015190505f83838151811061097657610975611af7565b5b602002602001015190505f612710828a6109909190611b51565b61099a9190611bbf565b90505f811115610a64575f8873ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85846040518363ffffffff1660e01b81526004016109e0929190611945565b6020604051808303815f875af11580156109fc573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a2091906119a1565b905080610a62576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a5990611c39565b60405180910390fd5b505b505050808060010191505061093b565b50610a7d610f73565b73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167f28f83976a1606de6e0641f044ae0d7b6343bc4e8f258954281c8a90f21dcb101878585604051610add93929190611dc5565b60405180910390a350505050610af1610f7a565b5050565b610afd610b79565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610b6d575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401610b6491906114cd565b60405180910390fd5b610b7681610e63565b50565b610b81610f73565b73ffffffffffffffffffffffffffffffffffffffff16610b9f61039f565b73ffffffffffffffffffffffffffffffffffffffff1614610bfe57610bc2610f73565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401610bf591906114cd565b60405180910390fd5b565b8051825114610c44576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c3b90611e78565b60405180910390fd5b5f825111610c87576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c7e90611ee0565b60405180910390fd5b5f5f90505f5f90505b8351811015610db2575f73ffffffffffffffffffffffffffffffffffffffff16848281518110610cc357610cc2611af7565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603610d21576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d1890611f48565b60405180910390fd5b5f838281518110610d3557610d34611af7565b5b602002602001015111610d7d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d7490611fb0565b60405180910390fd5b828181518110610d9057610d8f611af7565b5b602002602001015182610da39190611fce565b91508080600101915050610c90565b506127108114610df7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dee9061204b565b60405180910390fd5b8260029080519060200190610e0d929190610f83565b508160039080519060200190610e2492919061100a565b507fe513d216117f51d2e3f1d22d007ed71d23a52c0bcc410e8258732d682fe3db938383604051610e56929190612069565b60405180910390a1505050565b5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60025f5403610f6a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f61906120e8565b60405180910390fd5b60025f81905550565b5f33905090565b60015f81905550565b828054828255905f5260205f20908101928215610ff9579160200282015b82811115610ff8578251825f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555091602001919060010190610fa1565b5b5090506110069190611055565b5090565b828054828255905f5260205f20908101928215611044579160200282015b82811115611043578251825591602001919060010190611028565b5b5090506110519190611055565b5090565b5b8082111561106c575f815f905550600101611056565b5090565b5f82825260208201905092915050565b7f455448207061796d656e747320617265206e6f7420616c6c6f776564206469725f8201527f6563746c792e205573652073706c6974416e645472616e73666572546f6b656e60208201527f20666f7220746f6b656e732e0000000000000000000000000000000000000000604082015250565b5f611100604c83611070565b915061110b82611080565b606082019050919050565b5f6020820190508181035f83015261112d816110f4565b9050919050565b5f604051905090565b5f5ffd5b5f5ffd5b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61118f82611149565b810181811067ffffffffffffffff821117156111ae576111ad611159565b5b80604052505050565b5f6111c0611134565b90506111cc8282611186565b919050565b5f67ffffffffffffffff8211156111eb576111ea611159565b5b602082029050602081019050919050565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61122982611200565b9050919050565b6112398161121f565b8114611243575f5ffd5b50565b5f8135905061125481611230565b92915050565b5f61126c611267846111d1565b6111b7565b9050808382526020820190506020840283018581111561128f5761128e6111fc565b5b835b818110156112b857806112a48882611246565b845260208401935050602081019050611291565b5050509392505050565b5f82601f8301126112d6576112d5611145565b5b81356112e684826020860161125a565b91505092915050565b5f67ffffffffffffffff82111561130957611308611159565b5b602082029050602081019050919050565b5f819050919050565b61132c8161131a565b8114611336575f5ffd5b50565b5f8135905061134781611323565b92915050565b5f61135f61135a846112ef565b6111b7565b90508083825260208201905060208402830185811115611382576113816111fc565b5b835b818110156113ab57806113978882611339565b845260208401935050602081019050611384565b5050509392505050565b5f82601f8301126113c9576113c8611145565b5b81356113d984826020860161134d565b91505092915050565b5f5f604083850312156113f8576113f761113d565b5b5f83013567ffffffffffffffff81111561141557611414611141565b5b611421858286016112c2565b925050602083013567ffffffffffffffff81111561144257611441611141565b5b61144e858286016113b5565b9150509250929050565b5f61146282611200565b9050919050565b61147281611458565b811461147c575f5ffd5b50565b5f8135905061148d81611469565b92915050565b5f602082840312156114a8576114a761113d565b5b5f6114b58482850161147f565b91505092915050565b6114c78161121f565b82525050565b5f6020820190506114e05f8301846114be565b92915050565b5f5f5f606084860312156114fd576114fc61113d565b5b5f61150a86828701611246565b935050602061151b86828701611246565b925050604061152c86828701611339565b9150509250925092565b5f5f6040838503121561154c5761154b61113d565b5b5f61155985828601611246565b925050602061156a85828601611339565b9150509250929050565b5f602082840312156115895761158861113d565b5b5f61159684828501611246565b91505092915050565b7f496e76616c6964206164647265737300000000000000000000000000000000005f82015250565b5f6115d3600f83611070565b91506115de8261159f565b602082019050919050565b5f6020820190508181035f830152611600816115c7565b9050919050565b7f4e6f204554482062616c616e636520746f2077697468647261770000000000005f82015250565b5f61163b601a83611070565b915061164682611607565b602082019050919050565b5f6020820190508181035f8301526116688161162f565b9050919050565b5f81905092915050565b50565b5f6116875f8361166f565b915061169282611679565b5f82019050919050565b5f6116a68261167c565b9150819050919050565b7f455448207472616e73666572206661696c6564000000000000000000000000005f82015250565b5f6116e4601383611070565b91506116ef826116b0565b602082019050919050565b5f6020820190508181035f830152611711816116d8565b9050919050565b6117218161131a565b82525050565b5f60208201905061173a5f830184611718565b92915050565b7f546f6b656e2061646472657373206973207a65726f00000000000000000000005f82015250565b5f611774601583611070565b915061177f82611740565b602082019050919050565b5f6020820190508181035f8301526117a181611768565b9050919050565b7f526563697069656e742061646472657373206973207a65726f000000000000005f82015250565b5f6117dc601983611070565b91506117e7826117a8565b602082019050919050565b5f6020820190508181035f830152611809816117d0565b9050919050565b7f416d6f756e74206d7573742062652067726561746572207468616e207a65726f5f82015250565b5f611844602083611070565b915061184f82611810565b602082019050919050565b5f6020820190508181035f83015261187181611838565b9050919050565b5f8151905061188681611323565b92915050565b5f602082840312156118a1576118a061113d565b5b5f6118ae84828501611878565b91505092915050565b7f496e73756666696369656e7420746f6b656e2062616c616e636520696e20636f5f8201527f6e74726163740000000000000000000000000000000000000000000000000000602082015250565b5f611911602683611070565b915061191c826118b7565b604082019050919050565b5f6020820190508181035f83015261193e81611905565b9050919050565b5f6040820190506119585f8301856114be565b6119656020830184611718565b9392505050565b5f8115159050919050565b6119808161196c565b811461198a575f5ffd5b50565b5f8151905061199b81611977565b92915050565b5f602082840312156119b6576119b561113d565b5b5f6119c38482850161198d565b91505092915050565b7f546f6b656e20726573637565207472616e73666572206661696c6564000000005f82015250565b5f611a00601c83611070565b9150611a0b826119cc565b602082019050919050565b5f6020820190508181035f830152611a2d816119f4565b9050919050565b5f606082019050611a475f8301866114be565b611a5460208301856114be565b611a616040830184611718565b949350505050565b7f546f6b656e2070756c6c206661696c6564202d20436865636b20417070726f765f8201527f6520616c6c6f77616e6365000000000000000000000000000000000000000000602082015250565b5f611ac3602b83611070565b9150611ace82611a69565b604082019050919050565b5f6020820190508181035f830152611af081611ab7565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f611b5b8261131a565b9150611b668361131a565b9250828202611b748161131a565b91508282048414831517611b8b57611b8a611b24565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f611bc98261131a565b9150611bd48361131a565b925082611be457611be3611b92565b5b828204905092915050565b7f546f6b656e207472616e7366657220746f207061796565206661696c656400005f82015250565b5f611c23601e83611070565b9150611c2e82611bef565b602082019050919050565b5f6020820190508181035f830152611c5081611c17565b9050919050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b611c898161121f565b82525050565b5f611c9a8383611c80565b60208301905092915050565b5f602082019050919050565b5f611cbc82611c57565b611cc68185611c61565b9350611cd183611c71565b805f5b83811015611d01578151611ce88882611c8f565b9750611cf383611ca6565b925050600181019050611cd4565b5085935050505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b611d408161131a565b82525050565b5f611d518383611d37565b60208301905092915050565b5f602082019050919050565b5f611d7382611d0e565b611d7d8185611d18565b9350611d8883611d28565b805f5b83811015611db8578151611d9f8882611d46565b9750611daa83611d5d565b925050600181019050611d8b565b5085935050505092915050565b5f606082019050611dd85f830186611718565b8181036020830152611dea8185611cb2565b90508181036040830152611dfe8184611d69565b9050949350505050565b7f50617965657320616e6420736861726573206c656e677468206d69736d6174635f8201527f6800000000000000000000000000000000000000000000000000000000000000602082015250565b5f611e62602183611070565b9150611e6d82611e08565b604082019050919050565b5f6020820190508181035f830152611e8f81611e56565b9050919050565b7f4e6f207061796565732070726f766964656400000000000000000000000000005f82015250565b5f611eca601283611070565b9150611ed582611e96565b602082019050919050565b5f6020820190508181035f830152611ef781611ebe565b9050919050565b7f50617965652061646472657373206973207a65726f00000000000000000000005f82015250565b5f611f32601583611070565b9150611f3d82611efe565b602082019050919050565b5f6020820190508181035f830152611f5f81611f26565b9050919050565b7f5368617265206d7573742062652067726561746572207468616e207a65726f005f82015250565b5f611f9a601f83611070565b9150611fa582611f66565b602082019050919050565b5f6020820190508181035f830152611fc781611f8e565b9050919050565b5f611fd88261131a565b9150611fe38361131a565b9250828201905080821115611ffb57611ffa611b24565b5b92915050565b7f536861726573206d7573742073756d20746f20313030303020283130302529005f82015250565b5f612035601f83611070565b915061204082612001565b602082019050919050565b5f6020820190508181035f83015261206281612029565b9050919050565b5f6040820190508181035f8301526120818185611cb2565b905081810360208301526120958184611d69565b90509392505050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c005f82015250565b5f6120d2601f83611070565b91506120dd8261209e565b602082019050919050565b5f6020820190508181035f8301526120ff816120c6565b905091905056fea26469706673582212206332a03056551c993c44bc989549467676de35f888ad1e064acc537e2033fbab64736f6c634300081e0033

Verified Source Code Full Match

Compiler: v0.8.30+commit.73712a01 EVM: prague Optimization: No
ERC20Splitter.sol 178 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/utils/Context.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

/**
 * @title ERC20Splitter
 * @notice عقد لسحب أي توكن ERC-20 من المُرسل وتوزيعه على عدة مستفيدين بنسب ثابتة.
 * @dev [تعديل 4]: يدعم أي توكن ERC-20 يتم تحديده عند الاستدعاء.
 * @dev [تعديل 3]: الـ Owner لديه القدرة على تغيير المستفيدين والحصص.
 */
contract ERC20Splitter is Context, ReentrancyGuard, Ownable {

    // --- المتغيرات الأساسية ---
    address[] private _payees; 
    uint256[] private _shares;
    uint256 private constant TOTAL_SHARES = 10000; // المجموع = 100%

    // --- الأحداث (Events) ---

    /**
     * @notice يُطلق هذا الحدث عند نجاح عملية التقسيم (لأغراض المراقبة).
     * @param tokenAddress عنوان التوكن الذي تم تقسيمه.
     * @param sender الشخص الذي قام بتنفيذ التقسيم.
     * @param totalAmount إجمالي المبلغ الذي تم تقسيمه.
     */
    event FundsSplit(
        address indexed tokenAddress,
        address indexed sender,
        uint256 totalAmount,
        address[] payees,
        uint256[] shares
    );

    event ETHWithdrawn(uint256 amount, address indexed to);
    event ERC20Rescued(address indexed token, uint256 amount, address indexed to);
    event PayeesUpdated(address[] newPayees, uint256[] newShares);

    /**
     * @notice دالة الإنشاء (Constructor)
     * @param payees قائمة العناوين المستفيدة.
     * @param shares قائمة النسب المقابلة (مجموعها 10000).
     */
    constructor(
        address[] memory payees,
        uint256[] memory shares
    ) payable Ownable(_msgSender()) {
        
        // التحقق من المدخلات وتعيينها
        _updatePayeesInternal(payees, shares);
    }

    /**
     * @notice الوظيفة الرئيسية: لسحب أي توكن ERC-20 من المُرسل وتوزيعه فورياً.
     * @param tokenAddress عنوان التوكن (ERC-20) المراد تقسيمه.
     * @param amountToSplit إجمالي مبلغ التوكن المراد سحبه وتوزيعه.
     */
    function splitAndTransferToken(
        address tokenAddress, 
        uint256 amountToSplit
    ) public nonReentrant {
        require(tokenAddress != address(0), "Token address is zero");
        require(amountToSplit > 0, "Amount must be greater than zero");

        // 1. تحديد التوكن المستخدم لهذه العملية
        IERC20 token = IERC20(tokenAddress);

        // 2. سحب التوكن من المُرسل (يتطلب موافقة Approve مسبقة)
        bool success = token.transferFrom(_msgSender(), address(this), amountToSplit);
        require(success, "Token pull failed - Check Approve allowance"); 

        // 3. التوزيع على المستفيدين
        address[] memory currentPayees = _payees;
        uint256[] memory currentShares = _shares;

        for (uint i = 0; i < currentPayees.length; i++) {
            address payee = currentPayees[i];
            uint256 share = currentShares[i];

            // الحساب
            uint256 amount = (amountToSplit * share) / TOTAL_SHARES;
            
            if (amount > 0) {
                // تنفيذ التحويل المباشر
                bool transferSuccess = token.transfer(payee, amount);
                require(transferSuccess, "Token transfer to payee failed");
            }
        }
        
        // 4. إطلاق الحدث (للمراقبة)
        emit FundsSplit(
            tokenAddress,
            _msgSender(), 
            amountToSplit, 
            currentPayees, 
            currentShares 
        );
    }

    // --- بقية الدوال كما هي ---

    /**
     * @notice وظيفة إدارية: لسحب أي ETH قد يتم إرساله عن طريق الخطأ.
     */
    function withdrawETH(address payable to) public onlyOwner {
        require(to != address(0), "Invalid address");
        uint256 balance = address(this).balance;
        require(balance > 0, "No ETH balance to withdraw");

        (bool success, ) = to.call{value: balance}("");
        require(success, "ETH transfer failed");

        emit ETHWithdrawn(balance, to);
    }

    /**
     * @notice وظيفة إدارية (للـ Owner): لإنقاذ أي توكن ERC20 تم إرساله بالخطأ إلى هذا العقد.
     */
    function rescueERC20(address tokenAddress, address to, uint256 amount) public onlyOwner {
        require(tokenAddress != address(0), "Token address is zero");
        require(to != address(0), "Recipient address is zero");
        require(amount > 0, "Amount must be greater than zero");

        IERC20 token = IERC20(tokenAddress);
        uint256 contractBalance = token.balanceOf(address(this));
        require(amount <= contractBalance, "Insufficient token balance in contract");

        bool success = token.transfer(to, amount);
        require(success, "Token rescue transfer failed");

        emit ERC20Rescued(tokenAddress, amount, to);
    }
    
    /**
     * @notice وظيفة إدارية (للـ Owner): لتحديث قائمة المستفيدين والحصص.
     */
    function updatePayeesAndShares(
        address[] memory newPayees,
        uint256[] memory newShares
    ) public onlyOwner {
        _updatePayeesInternal(newPayees, newShares);
    }

    /**
     * @notice دالة داخلية للتحقق من وتعيين المستفيدين والحصص.
     */
    function _updatePayeesInternal(
        address[] memory newPayees,
        uint256[] memory newShares
    ) private {
        require(newPayees.length == newShares.length, "Payees and shares length mismatch");
        require(newPayees.length > 0, "No payees provided");

        uint256 totalShares_ = 0;
        for (uint256 i = 0; i < newPayees.length; i++) {
            require(newPayees[i] != address(0), "Payee address is zero");
            require(newShares[i] > 0, "Share must be greater than zero");
            totalShares_ += newShares[i];
        }

        require(totalShares_ == TOTAL_SHARES, "Shares must sum to 10000 (100%)");

        _payees = newPayees;
        _shares = newShares;
        
        emit PayeesUpdated(newPayees, newShares);
    }

    /**
     * @notice رفض إرسال ETH مباشرة.
     */
    receive() external payable {
        revert("ETH payments are not allowed directly. Use splitAndTransferToken for tokens.");
    }
}
Ownable.sol 100 lines
// 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);
    }
}
ReentrancyGuard.sol 77 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be _NOT_ENTERED
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;
    }

    function _nonReentrantAfter() private {
        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
     * `nonReentrant` function in the call stack.
     */
    function _reentrancyGuardEntered() internal view returns (bool) {
        return _status == _ENTERED;
    }
}
Context.sol 28 lines
// 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;
    }
}
IERC20.sol 79 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)

pragma solidity >=0.4.16;

/**
 * @dev Interface of the ERC-20 standard as defined in the ERC.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the value of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the value of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves a `value` amount of tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 value) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the
     * caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 value) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to` using the
     * allowance mechanism. `value` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 value) external returns (bool);
}

Read Contract

owner 0x8da5cb5b → address

Write Contract 6 functions

These functions modify contract state and require a wallet transaction to execute.

renounceOwnership 0x715018a6
No parameters
rescueERC20 0xb2118a8d
address tokenAddress
address to
uint256 amount
splitAndTransferToken 0xd0de1ddc
address tokenAddress
uint256 amountToSplit
transferOwnership 0xf2fde38b
address newOwner
updatePayeesAndShares 0x469f0ab5
address[] newPayees
uint256[] newShares
withdrawETH 0x690d8320
address to

Recent Transactions

No transactions found for this address