Contrat

Contrat
0xa756f74dae…077649c15b

Solde WTG

17.498718 WTG

311,63 FCFA (@ 17,81 FCFA/WTG)

Avoirs en tokens

0 token

≈ 0,00 FCFA

Plus d'infos

Transactions envoyées1
Dernière activitéil y a 35 s
Première activitéil y a 18 h
Financé par

Code du contrat

✓ Vérifié

RewardDistributor · Solidity v0.8.20+commit.a1b79de6 · optimiseur activé (200 runs) · licence MIT

// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import { Ownable2Step, Ownable } from "@openzeppelin/contracts/access/Ownable2Step.sol";
import { ReentrancyGuard } from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";

interface IStakeManagerRewards {
    function distributeRewards() external payable;
}

/// @title RewardDistributor — QBFT block-reward beneficiary & fee settlement sink
/// @notice This is the `miningbeneficiary` configured in the QBFT genesis: every
///         block the protocol credits it the `blockreward` (the 1.5–2%/yr WTG
///         inflation). It also receives the validator-share of network/app fees.
///
///         Two native inflows are distinguished:
///           • block reward + already-burned fee remainder → arrive via receive(),
///             forwarded 100% to validators (burning inflation would be wrong).
///           • raw transaction fees → arrive via {depositFees}, which marks them
///             so that 20% is burned at settlement (the protocol burn policy).
///
///         At settlement, 20% of the *fee* bucket is burned to 0x…dEaD and the
///         remainder (block reward + 80% fees) is pushed to the StakeManager for
///         pro-rata distribution across the active validator set and delegators.
contract RewardDistributor is Ownable2Step, ReentrancyGuard {
    address public constant BURN_ADDRESS = 0x000000000000000000000000000000000000dEaD;
    uint16 public constant BPS = 10_000;

    IStakeManagerRewards public stakeManager;

    /// @notice Burn rate applied to the fee bucket at settlement (2000 = 20%).
    uint16 public feeBurnBps = 2_000;

    /// @notice Native WTG received as raw fees and pending settlement.
    uint256 public feePending;

    uint256 public totalBlockRewards;
    uint256 public totalFeesIn;
    uint256 public totalBurned;
    uint256 public totalDistributed;

    event BlockRewardReceived(uint256 amount);
    event FeesReceived(address indexed from, uint256 amount);
    event Settled(uint256 burned, uint256 distributed);
    event FeeBurnBpsUpdated(uint16 oldBps, uint16 newBps);
    event StakeManagerUpdated(address indexed stakeManager);

    error ZeroAddress();
    error InvalidBps();
    error NothingToSettle();

    constructor(address stakeManager_, address owner_) Ownable(owner_) {
        if (stakeManager_ == address(0)) revert ZeroAddress();
        stakeManager = IStakeManagerRewards(stakeManager_);
    }

    /// @notice Intake for raw transaction fees subject to the 20% burn.
    ///         Called by the protocol fee router / relayer and by modules that
    ///         forward gas fees here.
    function depositFees() external payable {
        if (msg.value == 0) return;
        feePending += msg.value;
        totalFeesIn += msg.value;
        emit FeesReceived(msg.sender, msg.value);
    }

    /// @notice Settle: burn 20% of the fee bucket, distribute everything else
    ///         (block reward + 80% fees) to validators/delegators.
    function settle() external nonReentrant {
        uint256 bal = address(this).balance;
        if (bal == 0) revert NothingToSettle();

        uint256 burnAmount = (feePending * feeBurnBps) / BPS;
        feePending = 0;
        if (burnAmount > bal) burnAmount = bal; // safety
        uint256 distributable = bal - burnAmount;

        if (burnAmount > 0) {
            totalBurned += burnAmount;
            (bool burned, ) = BURN_ADDRESS.call{ value: burnAmount }("");
            require(burned, "RewardDistributor: burn failed");
        }
        if (distributable > 0) {
            totalDistributed += distributable;
            stakeManager.distributeRewards{ value: distributable }();
        }
        emit Settled(burnAmount, distributable);
    }

    // ----- governance -----

    function setFeeBurnBps(uint16 newBps) external onlyOwner {
        if (newBps > BPS) revert InvalidBps();
        emit FeeBurnBpsUpdated(feeBurnBps, newBps);
        feeBurnBps = newBps;
    }

    function setStakeManager(address sm) external onlyOwner {
        if (sm == address(0)) revert ZeroAddress();
        stakeManager = IStakeManagerRewards(sm);
        emit StakeManagerUpdated(sm);
    }

    /// @dev QBFT block reward (coinbase credit) and forwarded fee remainders land here.
    receive() external payable {
        totalBlockRewards += msg.value;
        emit BlockRewardReceived(msg.value);
    }
}
[
    {
        "type": "constructor",
        "inputs": [
            {
                "name": "stakeManager_",
                "type": "address",
                "internalType": "address"
            },
            {
                "name": "owner_",
                "type": "address",
                "internalType": "address"
            }
        ],
        "stateMutability": "nonpayable"
    },
    {
        "type": "receive",
        "stateMutability": "payable"
    },
    {
        "type": "function",
        "name": "BPS",
        "inputs": [],
        "outputs": [
            {
                "name": "",
                "type": "uint16",
                "internalType": "uint16"
            }
        ],
        "stateMutability": "view"
    },
    {
        "type": "function",
        "name": "BURN_ADDRESS",
        "inputs": [],
        "outputs": [
            {
                "name": "",
                "type": "address",
                "internalType": "address"
            }
        ],
        "stateMutability": "view"
    },
    {
        "type": "function",
        "name": "acceptOwnership",
        "inputs": [],
        "outputs": [],
        "stateMutability": "nonpayable"
    },
    {
        "type": "function",
        "name": "depositFees",
        "inputs": [],
        "outputs": [],
        "stateMutability": "payable"
    },
    {
        "type": "function",
        "name": "feeBurnBps",
        "inputs": [],
        "outputs": [
            {
                "name": "",
                "type": "uint16",
                "internalType": "uint16"
            }
        ],
        "stateMutability": "view"
    },
    {
        "type": "function",
        "name": "feePending",
        "inputs": [],
        "outputs": [
            {
                "name": "",
                "type": "uint256",
                "internalType": "uint256"
            }
        ],
        "stateMutability": "view"
    },
    {
        "type": "function",
        "name": "owner",
        "inputs": [],
        "outputs": [
            {
                "name": "",
                "type": "address",
                "internalType": "address"
            }
        ],
        "stateMutability": "view"
    },
    {
        "type": "function",
        "name": "pendingOwner",
        "inputs": [],
        "outputs": [
            {
                "name": "",
                "type": "address",
                "internalType": "address"
            }
        ],
        "stateMutability": "view"
    },
    {
        "type": "function",
        "name": "renounceOwnership",
        "inputs": [],
        "outputs": [],
        "stateMutability": "nonpayable"
    },
    {
        "type": "function",
        "name": "setFeeBurnBps",
        "inputs": [
            {
                "name": "newBps",
                "type": "uint16",
                "internalType": "uint16"
            }
        ],
        "outputs": [],
        "stateMutability": "nonpayable"
    },
    {
        "type": "function",
        "name": "setStakeManager",
        "inputs": [
            {
                "name": "sm",
                "type": "address",
                "internalType": "address"
            }
        ],
        "outputs": [],
        "stateMutability": "nonpayable"
    },
    {
        "type": "function",
        "name": "settle",
        "inputs": [],
        "outputs": [],
        "stateMutability": "nonpayable"
    },
    {
        "type": "function",
        "name": "stakeManager",
        "inputs": [],
        "outputs": [
            {
                "name": "",
                "type": "address",
                "internalType": "contract IStakeManagerRewards"
            }
        ],
        "stateMutability": "view"
    },
    {
        "type": "function",
        "name": "totalBlockRewards",
        "inputs": [],
        "outputs": [
            {
                "name": "",
                "type": "uint256",
                "internalType": "uint256"
            }
        ],
        "stateMutability": "view"
    },
    {
        "type": "function",
        "name": "totalBurned",
        "inputs": [],
        "outputs": [
            {
                "name": "",
                "type": "uint256",
                "internalType": "uint256"
            }
        ],
        "stateMutability": "view"
    },
    {
        "type": "function",
        "name": "totalDistributed",
        "inputs": [],
        "outputs": [
            {
                "name": "",
                "type": "uint256",
                "internalType": "uint256"
            }
        ],
        "stateMutability": "view"
    },
    {
        "type": "function",
        "name": "totalFeesIn",
        "inputs": [],
        "outputs": [
            {
                "name": "",
                "type": "uint256",
                "internalType": "uint256"
            }
        ],
        "stateMutability": "view"
    },
    {
        "type": "function",
        "name": "transferOwnership",
        "inputs": [
            {
                "name": "newOwner",
                "type": "address",
                "internalType": "address"
            }
        ],
        "outputs": [],
        "stateMutability": "nonpayable"
    },
    {
        "type": "event",
        "name": "BlockRewardReceived",
        "inputs": [
            {
                "name": "amount",
                "type": "uint256",
                "indexed": false,
                "internalType": "uint256"
            }
        ],
        "anonymous": false
    },
    {
        "type": "event",
        "name": "FeeBurnBpsUpdated",
        "inputs": [
            {
                "name": "oldBps",
                "type": "uint16",
                "indexed": false,
                "internalType": "uint16"
            },
            {
                "name": "newBps",
                "type": "uint16",
                "indexed": false,
                "internalType": "uint16"
            }
        ],
        "anonymous": false
    },
    {
        "type": "event",
        "name": "FeesReceived",
        "inputs": [
            {
                "name": "from",
                "type": "address",
                "indexed": true,
                "internalType": "address"
            },
            {
                "name": "amount",
                "type": "uint256",
                "indexed": false,
                "internalType": "uint256"
            }
        ],
        "anonymous": false
    },
    {
        "type": "event",
        "name": "OwnershipTransferStarted",
        "inputs": [
            {
                "name": "previousOwner",
                "type": "address",
                "indexed": true,
                "internalType": "address"
            },
            {
                "name": "newOwner",
                "type": "address",
                "indexed": true,
                "internalType": "address"
            }
        ],
        "anonymous": false
    },
    {
        "type": "event",
        "name": "OwnershipTransferred",
        "inputs": [
            {
                "name": "previousOwner",
                "type": "address",
                "indexed": true,
                "internalType": "address"
            },
            {
                "name": "newOwner",
                "type": "address",
                "indexed": true,
                "internalType": "address"
            }
        ],
        "anonymous": false
    },
    {
        "type": "event",
        "name": "Settled",
        "inputs": [
            {
                "name": "burned",
                "type": "uint256",
                "indexed": false,
                "internalType": "uint256"
            },
            {
                "name": "distributed",
                "type": "uint256",
                "indexed": false,
                "internalType": "uint256"
            }
        ],
        "anonymous": false
    },
    {
        "type": "event",
        "name": "StakeManagerUpdated",
        "inputs": [
            {
                "name": "stakeManager",
                "type": "address",
                "indexed": true,
                "internalType": "address"
            }
        ],
        "anonymous": false
    },
    {
        "type": "error",
        "name": "InvalidBps",
        "inputs": []
    },
    {
        "type": "error",
        "name": "NothingToSettle",
        "inputs": []
    },
    {
        "type": "error",
        "name": "OwnableInvalidOwner",
        "inputs": [
            {
                "name": "owner",
                "type": "address",
                "internalType": "address"
            }
        ]
    },
    {
        "type": "error",
        "name": "OwnableUnauthorizedAccount",
        "inputs": [
            {
                "name": "account",
                "type": "address",
                "internalType": "address"
            }
        ]
    },
    {
        "type": "error",
        "name": "ReentrancyGuardReentrantCall",
        "inputs": []
    },
    {
        "type": "error",
        "name": "ZeroAddress",
        "inputs": []
    }
]
0x604060808152600480361015610055575b50361561001b575f80fd5b60207f7181dcb6fe2d63f99c1a50bcadf653f97125398dafe17be204de3d681a5a6f469161004b346005546107af565b60055551348152a1005b5f90813560e01c9081630e7c67fc1461070157816311da60b4146104b35781631d5514f71461048d5781631ee56788146103ef578163249d39e9146103d257816326741e7d146103bb578163715018a6146103535781637542ff951461032a57816379ba50971461029e57816379cb75431461027f5781638da5cb5b14610257578163be8dd9be14610238578163c872df9514610219578163d89135cd146101fa578163e30c3978146101d1578163efca2eed146101b2578163f2fde38b14610143575063fccc28130361001057903461013f578160031936011261013f576020905161dead8152f35b5080fd5b90503461013f57602036600319011261013f57356001600160a01b03818116918290036101ae57610172610784565b600180546001600160a01b031916831790558254167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e227008380a380f35b8280fd5b82843461013f578160031936011261013f576020906008549051908152f35b82843461013f578160031936011261013f5760015490516001600160a01b039091168152602090f35b82843461013f578160031936011261013f576020906007549051908152f35b82843461013f578160031936011261013f576020906006549051908152f35b82843461013f578160031936011261013f576020906005549051908152f35b82843461013f578160031936011261013f57905490516001600160a01b039091168152602090f35b839150346101ae57826003193601126101ae5760209250549051908152f35b905082346101ae57826003193601126101ae57600154916001600160a01b039133838516036103135750506bffffffffffffffffffffffff60a01b8092166001555f549133908316175f553391167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a380f35b60249250519063118cdaa760e01b82523390820152fd5b82843461013f578160031936011261013f5760035490516001600160a01b039091168152602090f35b82346103b857806003193601126103b85761036c610784565b600180546001600160a01b03199081169091555f80549182168155906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b80fd5b82806003193601126103b8576103cf6107d0565b80f35b82843461013f578160031936011261013f57602090516127108152f35b905082346101ae5760203660031901126101ae5781359061ffff808316938484036104895761041c610784565b612710851161047b5750907fed9a829a2cfdde32a9397899dd9501ee46a6c93262182c040753e5f42d1ba05791600354948251918660a01c1682526020820152a161ffff60a01b1990911660a09190911b61ffff60a01b161760035580f35b825163c6cc5d7f60e01b8152fd5b8580fd5b82843461013f578160031936011261013f5760209061ffff60035460a01c169051908152f35b82843461013f578160031936011261013f5760028054146106f257600280554780156106e257835461ffff60035460a01c16908181029181830414901517156106cf576127109004908385558082116106c7575b818103908082116106b4578290816105df575b03610557575b7ff5b268a3ff315cc44ccceeef86259c9e8eef81ceecb14001543809115380dd6293945082519182526020820152a1600160025580f35b610563816008546107af565b6008556003546001600160a01b0316803b156105db57848291878651809481936306f4a2cd60e41b83525af180156105d1576105a0575b50610520565b67ffffffffffffffff81959295116105be578352929350838561059a565b634e487b7160e01b825260418652602482fd5b84513d87823e3d90fd5b8480fd5b906105ec906007546107af565b600755848080808661dead5af13d156106af5767ffffffffffffffff3d81811161069c57865191601f8201601f19908116603f011683019081118382101761068957875281528660203d92013e5b1561064657829061051a565b835162461bcd60e51b8152602081880152601e60248201527f5265776172644469737472696275746f723a206275726e206661696c656400006044820152606490fd5b634e487b7160e01b895260418a52602489fd5b634e487b7160e01b885260418952602488fd5b61063a565b634e487b7160e01b855260118652602485fd5b905080610507565b634e487b7160e01b845260118552602484fd5b8151630c30209d60e31b81528490fd5b51633ee5aeb560e01b81529050fd5b839150346101ae5760203660031901126101ae5780356001600160a01b038116929083900361078057610732610784565b8215610773575050600380546001600160a01b031916821790557f18c7cdf94f8233bc399bdc8cb14514437756e7e9c583510d72b3a337f33b14a78280a280f35b5163d92e233d60e01b8152fd5b8380fd5b5f546001600160a01b0316330361079757565b60405163118cdaa760e01b8152336004820152602490fd5b919082018092116107bc57565b634e487b7160e01b5f52601160045260245ffd5b3415610822576107e2346004546107af565b6004556107f1346006546107af565b6006556040513481527f2ccfc58c2cef4ee590b5f16be0548cc54afc12e1c66a67b362b7d640fd16bb2d60203392a2565b56fea264697066735822122001790f8388c1f3f30c77e77a841b455a3566ba0575c4e76935ff011424268eb764736f6c63430008140033
HashMéthodeBlocÂgeDeÀMontantFrais
0x2c7b38025e… Règlement 46 404 il y a 35 s 0x835164…ee75cc ENTR. 0xa756f7…49c15b 0.00075372 WTG
0x78a9287de6… Règlement 46 378 il y a 1 min 0x835164…ee75cc ENTR. 0xa756f7…49c15b 0.00077789 WTG
0xfb32b42041… Règlement 46 357 il y a 2 min 0x835164…ee75cc ENTR. 0xa756f7…49c15b 0.00093462 WTG
0xa441eaf77d… Règlement 46 330 il y a 4 min 0x835164…ee75cc ENTR. 0xa756f7…49c15b 0.00083757 WTG
0xc86c0ab87e… Règlement 46 302 il y a 5 min 0x835164…ee75cc ENTR. 0xa756f7…49c15b 0.00080043 WTG
0xbd3be22218… Règlement 46 282 il y a 6 min 0x835164…ee75cc ENTR. 0xa756f7…49c15b 0.00065509 WTG
0x7d721249ff… Règlement 46 262 il y a 7 min 0x835164…ee75cc ENTR. 0xa756f7…49c15b 0.00071434 WTG
0x0409df3aba… Règlement 46 240 il y a 8 min 0x835164…ee75cc ENTR. 0xa756f7…49c15b 0.0007347 WTG
0x71c2829c4a… Règlement 46 220 il y a 9 min 0x835164…ee75cc ENTR. 0xa756f7…49c15b 0.00058424 WTG
0xf685d501ff… Règlement 46 201 il y a 10 min 0x835164…ee75cc ENTR. 0xa756f7…49c15b 0.00060773 WTG
0x9d890c2740… Règlement 46 179 il y a 11 min 0x835164…ee75cc ENTR. 0xa756f7…49c15b 0.00062394 WTG
0xdd213e1822… Règlement 46 141 il y a 13 min 0x835164…ee75cc ENTR. 0xa756f7…49c15b 0.00062095 WTG
0xee3ecacd90… Règlement 46 115 il y a 15 min 0x835164…ee75cc ENTR. 0xa756f7…49c15b 0.00069301 WTG
0xb52eec32e4… Règlement 46 095 il y a 16 min 0x835164…ee75cc ENTR. 0xa756f7…49c15b 0.0006863 WTG
0xbb0a4d825d… Règlement 46 067 il y a 17 min 0x835164…ee75cc ENTR. 0xa756f7…49c15b 0.00057975 WTG
0x710e3dc135… Règlement 46 041 il y a 18 min 0x835164…ee75cc ENTR. 0xa756f7…49c15b 0.00057254 WTG
0xcd38826ff1… Règlement 46 021 il y a 19 min 0x835164…ee75cc ENTR. 0xa756f7…49c15b 0.00061177 WTG
0x567afcd163… Règlement 46 002 il y a 20 min 0x835164…ee75cc ENTR. 0xa756f7…49c15b 0.00068196 WTG
0x29beb367dd… Règlement 45 977 il y a 21 min 0x835164…ee75cc ENTR. 0xa756f7…49c15b 0.00053632 WTG
0x23230f601a… Règlement 45 954 il y a 23 min 0x835164…ee75cc ENTR. 0xa756f7…49c15b 0.00061875 WTG
0x7fdf155477… Règlement 45 926 il y a 24 min 0x835164…ee75cc ENTR. 0xa756f7…49c15b 0.00056932 WTG
0xc9713d4baf… Règlement 45 903 il y a 25 min 0x835164…ee75cc ENTR. 0xa756f7…49c15b 0.00048144 WTG
0xced5a0f8bb… Règlement 45 875 il y a 27 min 0x835164…ee75cc ENTR. 0xa756f7…49c15b 0.00048552 WTG
0x95402d7a10… Règlement 45 846 il y a 28 min 0x835164…ee75cc ENTR. 0xa756f7…49c15b 0.0005957 WTG
0x33a75179f1… Règlement 45 823 il y a 29 min 0x835164…ee75cc ENTR. 0xa756f7…49c15b 0.00059751 WTG
Aucun transfert de token.
Tx parenteTypeDeÀValeur
0x2c7b3802…aeda48 appel 0xa756f7…49c15b 0xb9a9f0…1b7b8f 37.855767 WTG
≈ 674,16 FCFA
0x78a9287d…2d3799 appel 0xa756f7…49c15b 0xb9a9f0…1b7b8f 30.534082 WTG
≈ 543,77 FCFA
0xfb32b420…e8f8ef appel 0xa756f7…49c15b 0xb9a9f0…1b7b8f 39.358394 WTG
≈ 700,92 FCFA
0xa441eaf7…833f0b appel 0xa756f7…49c15b 0xb9a9f0…1b7b8f 40.802895 WTG
≈ 726,64 FCFA
0xc86c0ab8…34ebb9 appel 0xa756f7…49c15b 0xb9a9f0…1b7b8f 29.20377 WTG
≈ 520,08 FCFA
0xbd3be222…e04960 appel 0xa756f7…49c15b 0xb9a9f0…1b7b8f 29.105008 WTG
≈ 518,32 FCFA
0x7d721249…787e49 appel 0xa756f7…49c15b 0xb9a9f0…1b7b8f 32.037796 WTG
≈ 570,55 FCFA
0x0409df3a…4cbfbc appel 0xa756f7…49c15b 0xb9a9f0…1b7b8f 29.210668 WTG
≈ 520,20 FCFA
0x71c2829c…baf566 appel 0xa756f7…49c15b 0xb9a9f0…1b7b8f 27.669266 WTG
≈ 492,75 FCFA
0xf685d501…b59bcc appel 0xa756f7…49c15b 0xb9a9f0…1b7b8f 32.040291 WTG
≈ 570,59 FCFA
0x9d890c27…53d4cb appel 0xa756f7…49c15b 0xb9a9f0…1b7b8f 55.359191 WTG
≈ 985,87 FCFA
0xdd213e18…2b4c2e appel 0xa756f7…49c15b 0xb9a9f0…1b7b8f 37.845354 WTG
≈ 673,97 FCFA
0xee3ecacd…d202d9 appel 0xa756f7…49c15b 0xb9a9f0…1b7b8f 29.1371 WTG
≈ 518,89 FCFA
0xb52eec32…9d4ae3 appel 0xa756f7…49c15b 0xb9a9f0…1b7b8f 40.848436 WTG
≈ 727,45 FCFA
0xbb0a4d82…1f9b6c appel 0xa756f7…49c15b 0xb9a9f0…1b7b8f 37.884375 WTG
≈ 674,67 FCFA
0x710e3dc1…4eb2b5 appel 0xa756f7…49c15b 0xb9a9f0…1b7b8f 29.121657 WTG
≈ 518,62 FCFA
0xcd38826f…c315b2 appel 0xa756f7…49c15b 0xb9a9f0…1b7b8f 27.644231 WTG
≈ 492,31 FCFA
0x567afcd1…305166 appel 0xa756f7…49c15b 0xb9a9f0…1b7b8f 36.499044 WTG
≈ 650,00 FCFA
0x29beb367…74754d appel 0xa756f7…49c15b 0xb9a9f0…1b7b8f 33.459233 WTG
≈ 595,86 FCFA
0x23230f60…f7eb42 appel 0xa756f7…49c15b 0xb9a9f0…1b7b8f 40.815974 WTG
≈ 726,88 FCFA
0x7fdf1554…cc7826 appel 0xa756f7…49c15b 0xb9a9f0…1b7b8f 33.570463 WTG
≈ 597,84 FCFA
0xc9713d4b…345cb0 appel 0xa756f7…49c15b 0xb9a9f0…1b7b8f 40.788209 WTG
≈ 726,38 FCFA
0xced5a0f8…0b56b6 appel 0xa756f7…49c15b 0xb9a9f0…1b7b8f 42.17528 WTG
≈ 751,08 FCFA
0x95402d7a…4be7e1 appel 0xa756f7…49c15b 0xb9a9f0…1b7b8f 33.497816 WTG
≈ 596,55 FCFA
0x33a75179…6e4555 appel 0xa756f7…49c15b 0xb9a9f0…1b7b8f 35.074267 WTG
≈ 624,62 FCFA