Cryo Explorer Ethereum Mainnet

Address Contract Partially Verified

Address 0xb6cbFfeab1434a0D73F1706c1389378325feBB96
Balance 0 ETH
Nonce 1
Code Size 7702 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

7702 bytes
0x60806040526004361015610011575f80fd5b5f3560e01c806306fdde03146101f4578063095ea7b3146101ef57806318160ddd146101ea5780632355a6c1146101e557806323b872dd146101e0578063313ce567146101db5780633f4ba83a146101d657806343afb798146101d15780634f0580ae146101cc5780635c975abb146101c757806366e305fd146101c257806370a08231146101bd578063715018a6146101b857806379ba5097146101b35780638456cb59146101ae5780638da5cb5b146101a957806395d89b41146101a4578063a1c684d61461019f578063a8e560251461019a578063a9059cbb14610195578063af9c6a1d14610190578063b2fc90671461018b578063cdb7d1a314610186578063d1ee011714610181578063d39bed821461017c578063dd62ed3e14610177578063e30c397814610172578063ec6535d31461016d578063f20fb947146101685763f2fde38b14610163575f80fd5b610eb1565b610e8b565b610e4a565b610e24565b610dc3565b610d82565b610d65565b610cda565b610c3f565b610c1a565b610be5565b610ba4565b610b77565b610ac2565b610a9c565b6109e5565b610913565b61087a565b610839565b610808565b6107e3565b61078f565b6106d1565b610609565b6105ee565b610502565b6104a3565b610486565b610396565b61024f565b5f91031261020357565b5f80fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f602060409481855280519182918282880152018686015e5f8582860101520116010190565b34610203575f600319360112610203576040515f6003548060011c906001811690811561036f575b60208310821461034257828552602085019190811561030b57506001146102b9575b6102b5846102a981860382610f68565b60405191829182610207565b0390f35b60035f9081529250907fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b5b8184106102f7575050016102a982610299565b8054848401526020909301926001016102e4565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001682525090151560051b0190506102a982610299565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b91607f1691610277565b6001600160a01b031690565b6001600160a01b0381160361020357565b34610203576040600319360112610203576004356103b381610385565b602435331561045a576001600160a01b03821691821561042e576103f48291335f52600160205260405f20906001600160a01b03165f5260205260405f2090565b5560405190815233907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590602090a3602060405160018152f35b7f94280d62000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b7fe602df05000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b34610203575f600319360112610203576020600254604051908152f35b346102035760206003193601126102035760043567ffffffffffffffff8111610203573660238201121561020357806004013567ffffffffffffffff8111610203573660248260051b840101116102035760246105009201610fae565b005b346102035760606003193601126102035760043561051f81610385565b60243561052b81610385565b604435906001600160a01b0383165f52600160205261055e3360405f20906001600160a01b03165f5260205260405f2090565b54927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff841061059e575b6105929350611946565b60405160018152602090f35b8284106105ba576105b58361059295033383611baf565b610588565b82847ffb8f41b2000000000000000000000000000000000000000000000000000000005f523360045260245260445260645ffd5b34610203575f60031936011261020357602060405160128152f35b34610203575f60031936011261020357610621611932565b60065460ff8160a01c1615610681577fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff166006557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6020604051338152a1005b7f8dfc202b000000000000000000000000000000000000000000000000000000005f5260045ffd5b6003196040910112610203576004356106c181610385565b9060243580151581036102035790565b34610203576001600160a01b036106e7366106a9565b91906106f1611932565b169081156107675760207f9e3ebd48f41c4344ba38d41e99316e82579b66a37373942441df24610a5c293e91835f526009825261075c8160405f209060ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0083541691151516179055565b6040519015158152a2005b7fd92e233d000000000000000000000000000000000000000000000000000000005f5260045ffd5b34610203576020600319360112610203577f873f87739a207a08766288846aa959ce46341c9cb72597b5db7c036f553a8eaf60406004356107ce611932565b600754908060075582519182526020820152a1005b34610203575f60031936011261020357602060ff60065460a01c166040519015158152f35b3461020357602060031936011261020357602061082f60043561082a81610385565b6114cd565b6040519015158152f35b3461020357602060031936011261020357602061087260043561085b81610385565b6001600160a01b03165f525f60205260405f205490565b604051908152f35b34610203575f60031936011261020357610892611932565b7fffffffffffffffffffffffff0000000000000000000000000000000000000000600654166006555f6001600160a01b036005547fffffffffffffffffffffffff00000000000000000000000000000000000000008116600555167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b34610203575f60031936011261020357336001600160a01b0360065416036109b9577fffffffffffffffffffffffff000000000000000000000000000000000000000060065416600655600554337fffffffffffffffffffffffff00000000000000000000000000000000000000008216176005556001600160a01b033391167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3005b7f118cdaa7000000000000000000000000000000000000000000000000000000005f523360045260245ffd5b34610203575f600319360112610203576109fd611932565b60065460ff8160a01c16610a74577fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff740100000000000000000000000000000000000000009116176006557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586020604051338152a1005b7fd93c0665000000000000000000000000000000000000000000000000000000005f5260045ffd5b34610203575f6003193601126102035760206001600160a01b0360055416604051908152f35b34610203575f600319360112610203576040515f6004548060011c9060018116908115610b6d575b60208310821461034257828552602085019190811561030b5750600114610b1b576102b5846102a981860382610f68565b60045f9081529250907f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b5b818410610b59575050016102a982610299565b805484840152602090930192600101610b46565b91607f1691610aea565b3461020357602060031936011261020357610500600435610b9781610385565b610b9f611932565b6115a3565b34610203576020600319360112610203576001600160a01b03600435610bc981610385565b165f526009602052602060ff60405f2054166040519015158152f35b3461020357604060031936011261020357610c0f600435610c0581610385565b6024359033611946565b602060405160018152f35b34610203575f60031936011261020357602060ff600b5460a01c166040519015158152f35b3461020357610c4d366106a9565b90610c56611932565b6001600160a01b0381168015610767577fc1510ce9a1685d666df34d4db53865545c64aa8901b219af72bf372974764efb602061050094835f5260088252610ccc8160405f209060ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0083541691151516179055565b6040519015158152a2611a87565b34610203576001600160a01b03610cf0366106a9565b9190610cfa611932565b169081156107675760207fb1741ecbc3cb4b38bf7453853f3084ff484b1a8c00182c44bf11a593f8d1de9891835f52600a825261075c8160405f209060ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0083541691151516179055565b34610203575f600319360112610203576020600754604051908152f35b34610203576020600319360112610203576001600160a01b03600435610da781610385565b165f52600a602052602060ff60405f2054166040519015158152f35b34610203576040600319360112610203576020610e1b600435610de581610385565b6001600160a01b0360243591610dfa83610385565b165f526001835260405f20906001600160a01b03165f5260205260405f2090565b54604051908152f35b34610203575f6003193601126102035760206001600160a01b0360065416604051908152f35b34610203576020600319360112610203576001600160a01b03600435610e6f81610385565b165f526008602052602060ff60405f2054166040519015158152f35b34610203575f6003193601126102035760206001600160a01b03600b5416604051908152f35b34610203576020600319360112610203576001600160a01b03600435610ed681610385565b610ede611932565b16807fffffffffffffffffffffffff000000000000000000000000000000000000000060065416176006556001600160a01b03600554167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e227005f80a3005b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff821117610fa957604052565b610f3b565b90610fc091610fbb611932565b6111bc565b565b67ffffffffffffffff8111610fa95760051b60200190565b60408051909190610feb8382610f68565b60018152917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001366020840137565b9061102482610fc2565b6110316040519182610f68565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe061105f8294610fc2565b0190602036910137565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b91908110156110a65760051b0190565b611069565b356110b581610385565b90565b8051156110a65760200190565b80518210156110a65760209160051b010190565b604081016040825282518091526020606083019301905f5b818110611135575050506020818303910152602080835192838152019201905f5b81811061111f5750505090565b8251845260209384019390920191600101611112565b82516001600160a01b03168552602094850194909201916001016110f1565b6040513d5f823e3d90fd5b3d156111b7573d9067ffffffffffffffff8211610fa957604051916111ac60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160184610f68565b82523d5f602084013e565b606090565b600b54919060ff60a084901c16156111d3565b1590565b6114a5578115611418576111e68261101a565b926111f08361101a565b915f5b84811061143157505061037961120f916001600160a01b031690565b803b15610203575f60405180927fd32b95e6000000000000000000000000000000000000000000000000000000008252818381611250888b600484016110d9565b03925af1908161141d575b50611418577f99df7a4af0690438dacfc3e6b9d6de96e71161c22d8d42c592a0935235715c0f6112d661128c61115f565b5f9060048151101561140c575b50604080518681527fffffffff00000000000000000000000000000000000000000000000000000000909216602083015293949390918291820190565b0390a15f915b8183106112e95750505050565b611302610379600b96949596546001600160a01b031690565b61131c61130f86886110c5565b516001600160a01b031690565b61132686846110c5565b51823b15610203576040517f3825d8280000000000000000000000000000000000000000000000000000000081526001600160a01b039290921660048301526024820152905f908290604490829084905af190816113f2575b506113e65750505061138f61115f565b9182511561139f57825160208401fd5b61130f6113e3926113af926110c5565b7f9bd4565d000000000000000000000000000000000000000000000000000000005f526001600160a01b0316600452602490565b5ffd5b919392600101916112dc565b806114005f61140693610f68565b806101f9565b5f61137f565b6020915001515f611299565b505050565b806114005f61142b93610f68565b5f61125b565b806114476114426001938886611096565b6110ab565b61146381611455848b6110c5565b906001600160a01b03169052565b61146c816114cd565b1561149e5761148b906001600160a01b03165f525f60205260405f2090565b545b61149782876110c5565b52016111f3565b505f61148d565b7f87138d5c000000000000000000000000000000000000000000000000000000005f5260045ffd5b6001600160a01b03811690811561152357815f525f60205260405f205460075411611523573b1515908161150a575b5061150657600190565b5f90565b5f9081526008602052604081205460ff161591506114fc565b50505f90565b9081602091031261020357516110b581610385565b1561154557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f425558546f6b656e206e6f742073657420617320636f6e74726f6c6c657200006044820152fd5b600b5460a01c60ff1661190a576001600160a01b0316908115610767576115f8826001600160a01b03167fffffffffffffffffffffffff0000000000000000000000000000000000000000600b541617600b55565b61163c740100000000000000000000000000000000000000007fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff600b541617600b55565b604051917f448943092ead975433c953a53d30029ba593cd27e6b01dde932767576c62b1065f80a2611679610379600b546001600160a01b031690565b917ff77c4791000000000000000000000000000000000000000000000000000000008152602081600481865afa8015611905576116c8915f916118d6575b506001600160a01b0316301461153e565b6116d0610fda565b916116d9610fda565b906116f86116ef6005546001600160a01b031690565b611455866110b8565b61170761082a61130f866110b8565b156118d05761171b61085b61130f866110b8565b611724836110b8565b52803b15610203575f60405180927fd32b95e6000000000000000000000000000000000000000000000000000000008252818381611766888b600484016110d9565b03925af190816118bc575b506118b7577f99df7a4af0690438dacfc3e6b9d6de96e71161c22d8d42c592a0935235715c0f61179f61115f565b5f906004815110156118ab575b508451604080519182527fffffffff00000000000000000000000000000000000000000000000000000000929092166020820152a16117f6610379600b546001600160a01b031690565b9061180c61180661130f866110b8565b916110b8565b51823b15610203576040517f3825d8280000000000000000000000000000000000000000000000000000000081526001600160a01b039290921660048301526024820152905f908290604490829084905af19081611897575b50611893575061187361115f565b908151156118845750602081519101fd5b6113af61130f6113e3926110b8565b9050565b806114005f6118a593610f68565b5f611865565b6020915001515f6117ac565b509050565b806114005f6118ca93610f68565b5f611771565b5f61171b565b6118f8915060203d6020116118fe575b6118f08183610f68565b810190611529565b5f6116b7565b503d6118e6565b611154565b7f0dc149f0000000000000000000000000000000000000000000000000000000005f5260045ffd5b6001600160a01b036005541633036109b957565b916001600160a01b03831615611a5b576001600160a01b03821615611a2f57610fc09261198c61198c9261198060065460ff9060a01c1690565b611991575b8483611c95565b611a87565b6119a66103796005546001600160a01b031690565b33148015611a0b575b80156119e0575b80156119d9575b80156119d2575b6119cd90611bf6565b611985565b505f6119c4565b505f6119bd565b50611a066119ff866001600160a01b03165f52600960205260405f2090565b5460ff1690565b6119b6565b50611a2a6119ff846001600160a01b03165f52600960205260405f2090565b6119af565b7fec442f05000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b7f96c6fd1e000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b90600b54611a9c6111cf8260ff9060a01c1690565b6118b757611aa9836114cd565b15611b9b57611adc610379611ace856001600160a01b03165f525f60205260405f2090565b54926001600160a01b031690565b803b15610203576040517f3825d8280000000000000000000000000000000000000000000000000000000081526001600160a01b038516600482015260248101929092525f908290604490829084905af19081611b87575b506118935750611b4261115f565b90815115611b535750602081519101fd5b7f9bd4565d000000000000000000000000000000000000000000000000000000005f526001600160a01b031660045260245ffd5b806114005f611b9593610f68565b5f611b34565b611adc6103795f926001600160a01b031690565b6001600160a01b031690811561045a576001600160a01b0381161561042e57611bf3915f52600160205260405f20906001600160a01b03165f5260205260405f2090565b55565b15611bfd57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f425558546f6b656e3a20706175736564000000000000000000000000000000006044820152fd5b91908201809211611c6857565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b90916001600160a01b0382169182611d395750611d0f81611ce1611cdc7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef94600254611c5b565b600255565b6001600160a01b0385169485611d145750611cff8160025403600255565b6040519081529081906020820190565b0390a3565b611d2e906001600160a01b03165f525f60205260405f2090565b818154019055611cff565b611d53816001600160a01b03165f525f60205260405f2090565b54828110611da45791611d0f91611d9e827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9503916001600160a01b03165f525f60205260405f2090565b55611ce1565b7fe450d38c000000000000000000000000000000000000000000000000000000005f526001600160a01b0390911660045260245260445260645ffdfea2646970667358221220873405cfc35cad0a6c10553e807f295e11654ff8476f9ae832d1c8c1a49c726a64736f6c634300081e0033

Verified Source Code Partial Match

Compiler: v0.8.30+commit.73712a01 EVM: prague Optimization: Yes (10000 runs)
BUXToken.sol 228 lines
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.30;

/**
 * @title BUXToken
 * @notice ERC20 token with weighted random selection integration
 * @author BUX Team
 */

import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {Ownable2Step} from "@openzeppelin/contracts/access/Ownable2Step.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {Pausable} from "@openzeppelin/contracts/utils/Pausable.sol";

interface ISortitionIndexMutable {
    function set(address account, uint256 weight) external;
    function setBatch(address[] calldata accounts, uint256[] calldata weights) external;
    function totalWeight() external view returns (uint256);
    function weightOf(address account) external view returns (uint256);
    function controller() external view returns (address);
}

contract BUXToken is ERC20, Ownable2Step, Pausable {
    error ZeroAddress();
    error AlreadyInitialized();
    error NotInitialized();
    error InitialRecipientMustBeContract();
    error WeightSyncFailed(address account);

    event MinEligibleBalanceUpdated(uint256 oldValue, uint256 newValue);
    event ContractEligibilitySet(address indexed account, bool isEligible);
    event PauseExemptSet(address indexed account, bool isExempt);
    event NoContagionSet(address indexed account, bool isNoContagion);
    event SortitionIndexInitialized(address indexed index);
    event SortitionIndexBatchRetried(uint256 count, bytes4 reasonSelector);

    uint256 private _minEligibleBalance;
    mapping(address => bool) public contractEligible;
    mapping(address => bool) public pauseExempt;
    mapping(address => bool) public noContagion;
    ISortitionIndexMutable private _index;
    bool public indexFrozen;

    constructor(
        string memory name_,
        string memory symbol_,
        address initialOwner,
        address initialRecipient,
        uint256 initialSupply,
        uint256 minEligibleBalance_
    ) ERC20(name_, symbol_) Ownable(initialOwner) {
        if (initialRecipient == address(0)) revert ZeroAddress();

        if (initialRecipient.code.length == 0) {
            revert InitialRecipientMustBeContract();
        }

        _minEligibleBalance = minEligibleBalance_;
        _mint(initialRecipient, initialSupply);
    }

    function pause() external onlyOwner {
        _pause();
    }

    function unpause() external onlyOwner {
        _unpause();
    }

    function setMinEligibleBalance(uint256 newMin) external onlyOwner {
        uint256 old = _minEligibleBalance;
        _minEligibleBalance = newMin;
        emit MinEligibleBalanceUpdated(old, newMin);
    }

    function setContractEligible(address account, bool allowed) external onlyOwner {
        if (account == address(0)) revert ZeroAddress();
        contractEligible[account] = allowed;
        emit ContractEligibilitySet(account, allowed);
        _pushWeight(account);
    }

    function setPauseExempt(address account, bool isExempt) external onlyOwner {
        if (account == address(0)) revert ZeroAddress();
        pauseExempt[account] = isExempt;
        emit PauseExemptSet(account, isExempt);
    }

    function setNoContagion(address account, bool isNoContagion) external onlyOwner {
        if (account == address(0)) revert ZeroAddress();
        noContagion[account] = isNoContagion;
        emit NoContagionSet(account, isNoContagion);
    }

    function initSortitionIndex(address index_) external onlyOwner {
        if (indexFrozen) revert AlreadyInitialized();
        if (index_ == address(0)) revert ZeroAddress();

        _index = ISortitionIndexMutable(index_);
        indexFrozen = true;
        emit SortitionIndexInitialized(index_);

        address ctl = _index.controller();
        require(ctl == address(this), "BUXToken not set as controller");

        address[] memory accounts = new address[](1);
        uint256[] memory weights = new uint256[](1);
        accounts[0] = owner();
        weights[0] = isEligible(accounts[0]) ? balanceOf(accounts[0]) : 0;

        try _index.setBatch(accounts, weights) {
            return;
        } catch (bytes memory reason) {
            bytes4 selector;
            if (reason.length >= 4) {
                assembly {
                    selector := mload(add(reason, 32))
                }
            }
            emit SortitionIndexBatchRetried(accounts.length, selector);

            try _index.set(accounts[0], weights[0]) {
                return;
            } catch (bytes memory singleReason) {
                if (singleReason.length == 0) revert WeightSyncFailed(accounts[0]);
                assembly {
                    revert(add(singleReason, 32), mload(singleReason))
                }
            }
        }
    }

    function resyncWeights(address[] calldata accounts) external onlyOwner {
        if (!indexFrozen) revert NotInitialized();
        uint256 len = accounts.length;
        if (len == 0) return;

        address[] memory addrs = new address[](len);
        uint256[] memory weights = new uint256[](len);
        unchecked {
            for (uint256 i = 0; i < len; i++) {
                address a = accounts[i];
                addrs[i] = a;
                weights[i] = isEligible(a) ? balanceOf(a) : 0;
            }
        }

        try _index.setBatch(addrs, weights) {
            return;
        } catch (bytes memory reason) {
            bytes4 selector;
            if (reason.length >= 4) {
                assembly {
                    selector := mload(add(reason, 32))
                }
            }
            emit SortitionIndexBatchRetried(len, selector);

            unchecked {
                for (uint256 i = 0; i < len; i++) {
                    try _index.set(addrs[i], weights[i]) {
                    } catch (bytes memory singleReason) {
                        if (singleReason.length == 0) revert WeightSyncFailed(addrs[i]);
                        assembly {
                            revert(add(singleReason, 32), mload(singleReason))
                        }
                    }
                }
            }
        }
    }

    function minEligibleBalance() external view returns (uint256) {
        return _minEligibleBalance;
    }

    function sortitionIndex() external view returns (address) {
        return address(_index);
    }

    function isEligible(address account) public view returns (bool) {
        if (account == address(0)) return false;

        uint256 bal = balanceOf(account);
        if (bal < _minEligibleBalance) return false;

        if (_hasCode(account) && !contractEligible[account]) {
            return false;
        }

        return true;
    }

    function _update(address from, address to, uint256 value) internal virtual override {
        if (paused()) {
            bool allowed =
                (msg.sender == owner()) ||
                (from != address(0) && pauseExempt[from]) ||
                (to != address(0) && pauseExempt[to]) ||
                (from == address(0) && msg.sender == owner()) ||
                (to == address(0) && msg.sender == owner());
            require(allowed, "BUXToken: paused");
        }

        super._update(from, to, value);

        if (from != address(0)) _pushWeight(from);
        if (to != address(0)) _pushWeight(to);
    }

    function _pushWeight(address account) internal {
        if (!indexFrozen) return;

        uint256 w = isEligible(account) ? balanceOf(account) : 0;

        try _index.set(account, w) {
        } catch (bytes memory reason) {
            if (reason.length == 0) revert WeightSyncFailed(account);
            assembly {
                revert(add(reason, 32), mload(reason))
            }
        }
    }

    function _hasCode(address account) internal view returns (bool) {
        return account.code.length > 0;
    }
}
ERC20.sol 305 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/ERC20.sol)

pragma solidity ^0.8.20;

import {IERC20} from "./IERC20.sol";
import {IERC20Metadata} from "./extensions/IERC20Metadata.sol";
import {Context} from "../../utils/Context.sol";
import {IERC20Errors} from "../../interfaces/draft-IERC6093.sol";

/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * The default value of {decimals} is 18. To change this, you should override
 * this function so it returns a different value.
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC-20
 * applications.
 */
abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {
    mapping(address account => uint256) private _balances;

    mapping(address account => mapping(address spender => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * Both values are immutable: they can only be set once during construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the default value returned by this function, unless
     * it's overridden.
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual returns (uint8) {
        return 18;
    }

    /// @inheritdoc IERC20
    function totalSupply() public view virtual returns (uint256) {
        return _totalSupply;
    }

    /// @inheritdoc IERC20
    function balanceOf(address account) public view virtual returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - the caller must have a balance of at least `value`.
     */
    function transfer(address to, uint256 value) public virtual returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, value);
        return true;
    }

    /// @inheritdoc IERC20
    function allowance(address owner, address spender) public view virtual returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on
     * `transferFrom`. This is semantically equivalent to an infinite approval.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 value) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, value);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Skips emitting an {Approval} event indicating an allowance update. This is not
     * required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve].
     *
     * NOTE: Does not update the allowance if the current allowance
     * is the maximum `uint256`.
     *
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `from` must have a balance of at least `value`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `value`.
     */
    function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, value);
        _transfer(from, to, value);
        return true;
    }

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead.
     */
    function _transfer(address from, address to, uint256 value) internal {
        if (from == address(0)) {
            revert ERC20InvalidSender(address(0));
        }
        if (to == address(0)) {
            revert ERC20InvalidReceiver(address(0));
        }
        _update(from, to, value);
    }

    /**
     * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`
     * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding
     * this function.
     *
     * Emits a {Transfer} event.
     */
    function _update(address from, address to, uint256 value) internal virtual {
        if (from == address(0)) {
            // Overflow check required: The rest of the code assumes that totalSupply never overflows
            _totalSupply += value;
        } else {
            uint256 fromBalance = _balances[from];
            if (fromBalance < value) {
                revert ERC20InsufficientBalance(from, fromBalance, value);
            }
            unchecked {
                // Overflow not possible: value <= fromBalance <= totalSupply.
                _balances[from] = fromBalance - value;
            }
        }

        if (to == address(0)) {
            unchecked {
                // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.
                _totalSupply -= value;
            }
        } else {
            unchecked {
                // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.
                _balances[to] += value;
            }
        }

        emit Transfer(from, to, value);
    }

    /**
     * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).
     * Relies on the `_update` mechanism
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead.
     */
    function _mint(address account, uint256 value) internal {
        if (account == address(0)) {
            revert ERC20InvalidReceiver(address(0));
        }
        _update(address(0), account, value);
    }

    /**
     * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.
     * Relies on the `_update` mechanism.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead
     */
    function _burn(address account, uint256 value) internal {
        if (account == address(0)) {
            revert ERC20InvalidSender(address(0));
        }
        _update(account, address(0), value);
    }

    /**
     * @dev Sets `value` as the allowance of `spender` over the `owner`'s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     *
     * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.
     */
    function _approve(address owner, address spender, uint256 value) internal {
        _approve(owner, spender, value, true);
    }

    /**
     * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.
     *
     * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by
     * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any
     * `Approval` event during `transferFrom` operations.
     *
     * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to
     * true using the following override:
     *
     * ```solidity
     * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {
     *     super._approve(owner, spender, value, true);
     * }
     * ```
     *
     * Requirements are the same as {_approve}.
     */
    function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {
        if (owner == address(0)) {
            revert ERC20InvalidApprover(address(0));
        }
        if (spender == address(0)) {
            revert ERC20InvalidSpender(address(0));
        }
        _allowances[owner][spender] = value;
        if (emitEvent) {
            emit Approval(owner, spender, value);
        }
    }

    /**
     * @dev Updates `owner`'s allowance for `spender` based on spent `value`.
     *
     * Does not update the allowance value in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Does not emit an {Approval} event.
     */
    function _spendAllowance(address owner, address spender, uint256 value) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance < type(uint256).max) {
            if (currentAllowance < value) {
                revert ERC20InsufficientAllowance(spender, currentAllowance, value);
            }
            unchecked {
                _approve(owner, spender, currentAllowance - value, false);
            }
        }
    }
}
Ownable2Step.sol 67 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.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.
 *
 * This extension of the {Ownable} contract includes a two-step mechanism to transfer
 * ownership, where the new owner must call {acceptOwnership} in order to replace the
 * old one. This can help prevent common mistakes, such as transfers of ownership to
 * incorrect accounts, or to contracts that are unable to interact with the
 * permission system.
 *
 * 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.
     *
     * Setting `newOwner` to the zero address is allowed; this can be used to cancel an initiated ownership transfer.
     */
    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);
    }
}
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);
    }
}
Pausable.sol 112 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (utils/Pausable.sol)

pragma solidity ^0.8.20;

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

/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
    bool private _paused;

    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    /**
     * @dev The operation failed because the contract is paused.
     */
    error EnforcedPause();

    /**
     * @dev The operation failed because the contract is not paused.
     */
    error ExpectedPause();

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        _requireNotPaused();
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        _requirePaused();
        _;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Throws if the contract is paused.
     */
    function _requireNotPaused() internal view virtual {
        if (paused()) {
            revert EnforcedPause();
        }
    }

    /**
     * @dev Throws if the contract is not paused.
     */
    function _requirePaused() internal view virtual {
        if (!paused()) {
            revert ExpectedPause();
        }
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
}
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);
}
IERC20Metadata.sol 26 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity >=0.6.2;

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

/**
 * @dev Interface for the optional metadata functions from the ERC-20 standard.
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}
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;
    }
}
draft-IERC6093.sol 161 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/draft-IERC6093.sol)
pragma solidity >=0.8.4;

/**
 * @dev Standard ERC-20 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens.
 */
interface IERC20Errors {
    /**
     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param balance Current balance for the interacting account.
     * @param needed Minimum amount required to perform a transfer.
     */
    error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC20InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC20InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.
     * @param spender Address that may be allowed to operate on tokens without being their owner.
     * @param allowance Amount of tokens a `spender` is allowed to operate with.
     * @param needed Minimum amount required to perform a transfer.
     */
    error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC20InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `spender` to be approved. Used in approvals.
     * @param spender Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC20InvalidSpender(address spender);
}

/**
 * @dev Standard ERC-721 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens.
 */
interface IERC721Errors {
    /**
     * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20.
     * Used in balance queries.
     * @param owner Address of the current owner of a token.
     */
    error ERC721InvalidOwner(address owner);

    /**
     * @dev Indicates a `tokenId` whose `owner` is the zero address.
     * @param tokenId Identifier number of a token.
     */
    error ERC721NonexistentToken(uint256 tokenId);

    /**
     * @dev Indicates an error related to the ownership over a particular token. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param tokenId Identifier number of a token.
     * @param owner Address of the current owner of a token.
     */
    error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC721InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC721InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     * @param tokenId Identifier number of a token.
     */
    error ERC721InsufficientApproval(address operator, uint256 tokenId);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC721InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC721InvalidOperator(address operator);
}

/**
 * @dev Standard ERC-1155 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens.
 */
interface IERC1155Errors {
    /**
     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param balance Current balance for the interacting account.
     * @param needed Minimum amount required to perform a transfer.
     * @param tokenId Identifier number of a token.
     */
    error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC1155InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC1155InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     * @param owner Address of the current owner of a token.
     */
    error ERC1155MissingApprovalForAll(address operator, address owner);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC1155InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC1155InvalidOperator(address operator);

    /**
     * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.
     * Used in batch transfers.
     * @param idsLength Length of the array of token identifiers
     * @param valuesLength Length of the array of token amounts
     */
    error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}

Read Contract

allowance 0xdd62ed3e → uint256
balanceOf 0x70a08231 → uint256
contractEligible 0xec6535d3 → bool
decimals 0x313ce567 → uint8
indexFrozen 0xaf9c6a1d → bool
isEligible 0x66e305fd → bool
minEligibleBalance 0xd1ee0117 → uint256
name 0x06fdde03 → string
noContagion 0xd39bed82 → bool
owner 0x8da5cb5b → address
pauseExempt 0xa8e56025 → bool
paused 0x5c975abb → bool
pendingOwner 0xe30c3978 → address
sortitionIndex 0xf20fb947 → address
symbol 0x95d89b41 → string
totalSupply 0x18160ddd → uint256

Write Contract 14 functions

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

acceptOwnership 0x79ba5097
No parameters
approve 0x095ea7b3
address spender
uint256 value
returns: bool
initSortitionIndex 0xa1c684d6
address index_
pause 0x8456cb59
No parameters
renounceOwnership 0x715018a6
No parameters
resyncWeights 0x2355a6c1
address[] accounts
setContractEligible 0xb2fc9067
address account
bool allowed
setMinEligibleBalance 0x4f0580ae
uint256 newMin
setNoContagion 0xcdb7d1a3
address account
bool isNoContagion
setPauseExempt 0x43afb798
address account
bool isExempt
transfer 0xa9059cbb
address to
uint256 value
returns: bool
transferFrom 0x23b872dd
address from
address to
uint256 value
returns: bool
transferOwnership 0xf2fde38b
address newOwner
unpause 0x3f4ba83a
No parameters

Recent Transactions

No transactions found for this address