ETH Price: $3,720.88 (-2.35%)

Transaction Decoder

Block:
12295804 at Apr-23-2021 09:57:50 AM +UTC
Transaction Fee:
0.0066104 ETH $24.60
Gas Used:
82,630 Gas / 80 Gwei

Emitted Events:

371 Forth.Transfer( from=[Receiver] ForthClaim, to=[Sender] 0x52d9ac072c5456d9547d73e5138b8395dbcb4614, amount=749268200149434515660 )
372 ForthClaim.Claimed( index=810, account=[Sender] 0x52d9ac072c5456d9547d73e5138b8395dbcb4614, amount=749268200149434515660 )

Account State Difference:

  Address   Before After State Difference Code
0x52D9AC07...5DBCB4614
0.014733715303865991 Eth
Nonce: 85
0.008123315303865991 Eth
Nonce: 86
0.0066104
0x77FbA179...0AdA60ce0
(Ethermine)
2,968.297858111988748574 Eth2,968.304468511988748574 Eth0.0066104
0xF497b83C...aF52d03A1

Execution Trace

ForthClaim.claim( )
  • Forth.transfer( dst=0x52D9AC072C5456D9547d73e5138b8395DBCB4614, rawAmount=749268200149434515660 ) => ( True )
    File 1 of 2: ForthClaim
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    // SPDX-License-Identifier: GPL-3.0-or-later
    pragma solidity 0.6.11;
    /*
    Extended Uniswap's MerkleDistributor.sol
    https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol
    */
    import {MerkleDistributor} from "@uniswap/merkle-distributor/contracts/MerkleDistributor.sol";
    import {MerkleProof} from "@openzeppelin/contracts/cryptography/MerkleProof.sol";
    import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
    interface IERC20 {
    function balanceOf(address account) external returns (uint256);
    function transfer(address to, uint256 amount) external;
    }
    contract ForthClaim is MerkleDistributor, Ownable {
    // Block timestamp representing deadline to claim. After this time, unclaimed tokens are burned.
    uint256 public immutable expiryTimestampSec;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 2 of 2: Forth
    1
    {"Forth.sol":{"content":"// SPDX-License-Identifier: BSD-3-Clause\n\npragma solidity 0.6.11;\npragma experimental ABIEncoderV2;\n\nimport \"./SafeMath
        .sol\";\n\ncontract Forth {\n /// @notice EIP-20 token name for this token\n string public constant name = \"Ampleforth Governance\";\n\n
        /// @notice EIP-20 token symbol for this token\n string public constant symbol = \"FORTH\";\n\n /// @notice EIP-20 token decimals for this
        token\n uint8 public constant decimals = 18;\n\n /// @notice Total number of tokens in circulation\n uint public totalSupply =
        15_000_000e18; // 15 million Forth\n\n /// @notice Address which may mint new tokens\n address public minter;\n\n /// @notice The
        timestamp after which minting may occur\n uint public mintingAllowedAfter;\n\n /// @notice Minimum time between mints\n uint32 public
        constant minimumTimeBetweenMints = 1 days * 365;\n\n /// @notice Cap on the percentage of totalSupply that can be minted at each mint\n uint8
        public constant mintCap = 2;\n\n /// @dev Allowance amounts on behalf of others\n mapping (address =\u003e mapping (address =\u003e uint96))
        internal allowances;\n\n /// @dev Official record of token balances for each account\n mapping (address =\u003e uint96) internal balances
        ;\n\n /// @notice A record of each accounts delegate\n mapping (address =\u003e address) public delegates;\n\n /// @notice A checkpoint
        for marking number of votes from a given block\n struct Checkpoint {\n uint32 fromBlock;\n uint96 votes;\n }\n\n /// @notice
        A record of votes checkpoints for each account, by index\n mapping (address =\u003e mapping (uint32 =\u003e Checkpoint)) public checkpoints;\n\n
         /// @notice The number of checkpoints for each account\n mapping (address =\u003e uint32) public numCheckpoints;\n\n /// @notice The EIP
        -712 typehash for the contract\u0027s domain\n bytes32 public constant DOMAIN_TYPEHASH = keccak256(\"EIP712Domain(string name,uint256 chainId
        ,address verifyingContract)\");\n\n /// @notice The EIP-712 typehash for the delegation struct used by the contract\n bytes32 public constant
        DELEGATION_TYPEHASH = keccak256(\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\");\n\n /// @notice The EIP-712 typehash for the
        permit struct used by the contract\n bytes32 public constant PERMIT_TYPEHASH = keccak256(\"Permit(address owner,address spender,uint256 value
        ,uint256 nonce,uint256 deadline)\");\n\n /// @notice A record of states for signing / validating signatures\n mapping (address =\u003e uint)
        public nonces;\n\n /// @notice An event thats emitted when the minter address is changed\n event MinterChanged(address minter, address
        newMinter);\n\n /// @notice An event thats emitted when an account changes its delegate\n event DelegateChanged(address indexed delegator,
        address indexed fromDelegate, address indexed toDelegate);\n\n /// @notice An event thats emitted when a delegate account\u0027s vote balance
        changes\n event DelegateVotesChanged(address indexed delegate, uint previousBalance, uint newBalance);\n\n /// @notice The standard EIP-20
        transfer event\n event Transfer(address indexed from, address indexed to, uint256 amount);\n\n /// @notice The standard EIP-20 approval
        event\n event Approval(address indexed owner, address indexed spender, uint256 amount);\n\n /**\n * @notice Construct a new Forth token\n
         * @param account The initial account to grant all the tokens\n * @param minter_ The account with minting ability\n * @param
        mintingAllowedAfter_ The timestamp after which minting may occur\n */\n constructor(address account, address minter_, uint
        mintingAllowedAfter_) public {\n require(mintingAllowedAfter_ \u003e= block.timestamp, \"Forth::constructor: minting can only begin after
        deployment\");\n\n balances[account] = uint96(totalSupply);\n emit Transfer(address(0), account, totalSupply);\n minter =
        minter_;\n emit MinterChanged(address(0), minter);\n mintingAllowedAfter = mintingAllowedAfter_;\n }\n\n /**\n * @notice
        Change the minter address\n * @param minter_ The address of the new minter\n */\n function setMinter(address minter_) external {\n
         require(msg.sender == minter, \"Forth::setMinter: only the minter can change the minter address\");\n emit MinterChanged(minter, minter_
        );\n minter = minter_;\n }\n\n /**\n * @notice Mint new tokens\n * @param dst The address of the destination account\n *
        @param rawAmount The number of tokens to be minted\n */\n function mint(address dst, uint rawAmount) external {\n require(msg.sender
        == minter, \"Forth::mint: only the minter can mint\");\n require(block.timestamp \u003e= mintingAllowedAfter, \"Forth::mint: minting not
        allowed yet\");\n require(dst != address(0), \"Forth::mint: cannot transfer to the zero address\");\n\n // record the mint\n
        mintingAllowedAfter = SafeMath.add(block.timestamp, minimumTimeBetweenMints);\n\n // mint the amount\n uint96 amount = safe96
        (rawAmount, \"Forth::mint: amount exceeds 96 bits\");\n require(amount \u003c= SafeMath.div(SafeMath.mul(totalSupply, mintCap), 100),
        \"Forth::mint: exceeded mint cap\");\n uint96 supply = safe96(totalSupply, \"Forth::mint old totalSupply exceeds 96 bits\");\n
        totalSupply = add96(supply, amount, \"Forth::mint: new totalSupply exceeds 96 bits\");\n\n // transfer the amount to the recipient\n
        balances[dst] = add96(balances[dst], amount, \"Forth::mint: transfer amount overflows\");\n emit Transfer(address(0), dst, amount);\n\n
         // move delegates\n _moveDelegates(address(0), delegates[dst], amount);\n }\n\n /**\n * @notice Destroys `amount` tokens from
        the caller\n * @param rawAmount The number of tokens to burn\n */\n function burn(uint256 rawAmount) external {\n uint96 amount =
        safe96(rawAmount, \"Forth::burn: rawAmount exceeds 96 bits\");\n _burn(msg.sender, amount);\n }\n\n /**\n * @notice Destroys
        `amount` tokens from `account`, deducting from the caller\u0027s allowance\n * @param account The address of the account to burn from\n *
        @param rawAmount The number of tokens to burn\n */\n function burnFrom(address account, uint256 rawAmount) external {\n uint96 amount
        = safe96(rawAmount, \"Forth::burnFrom: rawAmount exceeds 96 bits\");\n\n uint96 decreasedAllowance =\n sub96
        (allowances[account][msg.sender], amount, \"Forth::burnFrom: amount exceeds allowance\");\n allowances[account][msg.sender] =
        decreasedAllowance;\n emit Approval(account, msg.sender, decreasedAllowance);\n\n _burn(account, amount);\n }\n\n /**\n *
        @notice Destroys `amount` tokens from `account`, reducing the total supply\n * @param account The address of the account to burn from\n *
        @param amount The number of tokens to burn\n */\n function _burn(address account, uint96 amount) internal {\n require(account !=
        address(0), \"Forth::_burn: burn from the zero address\");\n\n uint96 supply = safe96(totalSupply, \"Forth::_burn: old supply exceeds 96
        bits\");\n totalSupply = sub96(supply, amount, \"Forth::_burn: amount exceeds totalSupply\");\n\n balances[account] = sub96
        (balances[account], amount, \"Forth::_burn: amount exceeds balance\");\n emit Transfer(account, address(0), amount);\n\n // move
        delegates\n _moveDelegates(delegates[account], address(0), amount);\n }\n\n /**\n * @notice Get the number of tokens `spender` is
        approved to spend on behalf of `account`\n * @param account The address of the account holding the funds\n * @param spender The address of
        the account spending the funds\n * @return The number of tokens approved\n */\n function allowance(address account, address spender)
        external view returns (uint) {\n return allowances[account][spender];\n }\n\n /**\n * @notice Approve `spender` to transfer up to
        `amount` from `src`\n * @dev This will overwrite the approval amount for `spender`\n * and is subject to issues noted [here](https://eips
        .ethereum.org/EIPS/eip-20#approve)\n * @param spender The address of the account which may transfer tokens\n * @param rawAmount The number
        of tokens that are approved (2^256-1 means infinite)\n * @return Whether or not the approval succeeded\n */\n function approve(address
        spender, uint rawAmount) external returns (bool) {\n uint96 amount;\n if (rawAmount == type(uint).max) {\n amount = type
        (uint96).max;\n } else {\n amount = safe96(rawAmount, \"Forth::approve: amount exceeds 96 bits\");\n }\n\n
        allowances[msg.sender][spender] = amount;\n\n emit Approval(msg.sender, spender, amount);\n return true;\n }\n\n /**\n *
        @notice Triggers an approval from owner to spends\n * @param owner The address to approve from\n * @param spender The address to be
        approved\n * @param rawAmount The number of tokens that are approved (2^256-1 means infinite)\n * @param deadline The time at which to
        expire the signature\n * @param v The recovery byte of the signature\n * @param r Half of the ECDSA signature pair\n * @param s Half of
        the ECDSA signature pair\n */\n function permit(address owner, address spender, uint rawAmount, uint deadline, uint8 v, bytes32 r, bytes32 s
        ) external {\n uint96 amount;\n if (rawAmount == type(uint).max) {\n amount = type(uint96).max;\n } else {\n
         amount = safe96(rawAmount, \"Forth::permit: amount exceeds 96 bits\");\n }\n\n bytes32 domainSeparator = keccak256(abi.encode
        (DOMAIN_TYPEHASH, keccak256(bytes(name)), getChainId(), address(this)));\n bytes32 structHash = keccak256(abi.encode(PERMIT_TYPEHASH, owner,
        spender, rawAmount, nonces[owner]++, deadline));\n bytes32 digest = keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash
        ));\n address signatory = ecrecover(digest, v, r, s);\n require(signatory != address(0), \"Forth::permit: invalid signature\");\n
         require(signatory == owner, \"Forth::permit: unauthorized\");\n require(now \u003c= deadline, \"Forth::permit: signature expired\");\n\n
         allowances[owner][spender] = amount;\n\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @notice Get the number of
        tokens held by the `account`\n * @param account The address of the account to get the balance of\n * @return The number of tokens held\n
         */\n function balanceOf(address account) external view returns (uint) {\n return balances[account];\n }\n\n /**\n * @notice
        Transfer `amount` tokens from `msg.sender` to `dst`\n * @param dst The address of the destination account\n * @param rawAmount The number
        of tokens to transfer\n * @return Whether or not the transfer succeeded\n */\n function transfer(address dst, uint rawAmount) external
        returns (bool) {\n uint96 amount = safe96(rawAmount, \"Forth::transfer: amount exceeds 96 bits\");\n _transferTokens(msg.sender, dst,
        amount);\n return true;\n }\n\n /**\n * @notice Transfer `amount` tokens from `src` to `dst`\n * @param src The address of the
        source account\n * @param dst The address of the destination account\n * @param rawAmount The number of tokens to transfer\n * @return
        Whether or not the transfer succeeded\n */\n function transferFrom(address src, address dst, uint rawAmount) external returns (bool) {\n
         address spender = msg.sender;\n uint96 spenderAllowance = allowances[src][spender];\n uint96 amount = safe96(rawAmount, \"Forth
        ::approve: amount exceeds 96 bits\");\n\n if (spender != src \u0026\u0026 spenderAllowance != type(uint96).max) {\n uint96
        newAllowance = sub96(spenderAllowance, amount, \"Forth::transferFrom: transfer amount exceeds spender allowance\");\n
        allowances[src][spender] = newAllowance;\n\n emit Approval(src, spender, newAllowance);\n }\n\n _transferTokens(src, dst,
        amount);\n return true;\n }\n\n /**\n * @notice Delegate votes from `msg.sender` to `delegatee`\n * @param delegatee The
        address to delegate votes to\n */\n function delegate(address delegatee) public {\n return _delegate(msg.sender, delegatee);\n
        }\n\n /**\n * @notice Delegates votes from signatory to `delegatee`\n * @param delegatee The address to delegate votes to\n * @param
        nonce The contract state required to match the signature\n * @param expiry The time at which to expire the signature\n * @param v The
        recovery byte of the signature\n * @param r Half of the ECDSA signature pair\n * @param s Half of the ECDSA signature pair\n */\n
        function delegateBySig(address delegatee, uint nonce, uint expiry, uint8 v, bytes32 r, bytes32 s) public {\n bytes32 domainSeparator =
        keccak256(abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name)), getChainId(), address(this)));\n bytes32 structHash = keccak256(abi.encode
        (DELEGATION_TYPEHASH, delegatee, nonce, expiry));\n bytes32 digest = keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash
        ));\n address signatory = ecrecover(digest, v, r, s);\n require(signatory != address(0), \"Forth::delegateBySig: invalid signature\"
        );\n require(nonce == nonces[signatory]++, \"Forth::delegateBySig: invalid nonce\");\n require(now \u003c= expiry, \"Forth
        ::delegateBySig: signature expired\");\n return _delegate(signatory, delegatee);\n }\n\n /**\n * @notice Gets the current votes
        balance for `account`\n * @param account The address to get votes balance\n * @return The number of current votes for `account`\n */\n
         function getCurrentVotes(address account) external view returns (uint96) {\n uint32 nCheckpoints = numCheckpoints[account];\n
        return nCheckpoints \u003e 0 ? checkpoints[account][nCheckpoints - 1].votes : 0;\n }\n\n /**\n * @notice Determine the prior number of
        votes for an account as of a block number\n * @dev Block number must be a finalized block or else this function will revert to prevent
        misinformation.\n * @param account The address of the account to check\n * @param blockNumber The block number to get the vote balance at\n
         * @return The number of votes the account had as of the given block\n */\n function getPriorVotes(address account, uint blockNumber)
        public view returns (uint96) {\n require(blockNumber \u003c block.number, \"Forth::getPriorVotes: not yet determined\");\n\n uint32
        nCheckpoints = numCheckpoints[account];\n if (nCheckpoints == 0) {\n return 0;\n }\n\n // First check most recent
        balance\n if (checkpoints[account][nCheckpoints - 1].fromBlock \u003c= blockNumber) {\n return checkpoints[account][nCheckpoints
        - 1].votes;\n }\n\n // Next check implicit zero balance\n if (checkpoints[account][0].fromBlock \u003e blockNumber) {\n
         return 0;\n }\n\n uint32 lower = 0;\n uint32 upper = nCheckpoints - 1;\n while (upper \u003e lower) {\n
         uint32 center = upper - (upper - lower) / 2; // ceil, avoiding overflow\n Checkpoint memory cp = checkpoints[account][center];\n
         if (cp.fromBlock == blockNumber) {\n return cp.votes;\n } else if (cp.fromBlock \u003c blockNumber) {\n
         lower = center;\n } else {\n upper = center - 1;\n }\n }\n return checkpoints[account][lower]
        .votes;\n }\n\n function _delegate(address delegator, address delegatee) internal {\n address currentDelegate = delegates[delegator]
        ;\n uint96 delegatorBalance = balances[delegator];\n delegates[delegator] = delegatee;\n\n emit DelegateChanged(delegator,
        currentDelegate, delegatee);\n\n _moveDelegates(currentDelegate, delegatee, delegatorBalance);\n }\n\n function _transferTokens
        (address src, address dst, uint96 amount) internal {\n require(src != address(0), \"Forth::_transferTokens: cannot transfer from the zero
        address\");\n require(dst != address(0), \"Forth::_transferTokens: cannot transfer to the zero address\");\n\n balances[src] = sub96
        (balances[src], amount, \"Forth::_transferTokens: transfer amount exceeds balance\");\n balances[dst] = add96(balances[dst], amount, \"Forth
        ::_transferTokens: transfer amount overflows\");\n emit Transfer(src, dst, amount);\n\n _moveDelegates(delegates[src], delegates[dst]
        , amount);\n }\n\n function _moveDelegates(address srcRep, address dstRep, uint96 amount) internal {\n if (srcRep != dstRep
        \u0026\u0026 amount \u003e 0) {\n if (srcRep != address(0)) {\n uint32 srcRepNum = numCheckpoints[srcRep];\n
         uint96 srcRepOld = srcRepNum \u003e 0 ? checkpoints[srcRep][srcRepNum - 1].votes : 0;\n uint96 srcRepNew = sub96(srcRepOld,
        amount, \"Forth::_moveVotes: vote amount underflows\");\n _writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew);\n
        }\n\n if (dstRep != address(0)) {\n uint32 dstRepNum = numCheckpoints[dstRep];\n uint96 dstRepOld =
        dstRepNum \u003e 0 ? checkpoints[dstRep][dstRepNum - 1].votes : 0;\n uint96 dstRepNew = add96(dstRepOld, amount, \"Forth::_moveVotes
        : vote amount overflows\");\n _writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew);\n }\n }\n }\n\n
        function _writeCheckpoint(address delegatee, uint32 nCheckpoints, uint96 oldVotes, uint96 newVotes) internal {\n uint32 blockNumber = safe32
        (block.number, \"Forth::_writeCheckpoint: block number exceeds 32 bits\");\n\n if (nCheckpoints \u003e 0 \u0026\u0026
        checkpoints[delegatee][nCheckpoints - 1].fromBlock == blockNumber) {\n checkpoints[delegatee][nCheckpoints - 1].votes = newVotes;\n }
        else {\n checkpoints[delegatee][nCheckpoints] = Checkpoint(blockNumber, newVotes);\n numCheckpoints[delegatee] = nCheckpoints + 1
        ;\n }\n\n emit DelegateVotesChanged(delegatee, oldVotes, newVotes);\n }\n\n function safe32(uint n, string memory errorMessage)
        internal pure returns (uint32) {\n require(n \u003c 2**32, errorMessage);\n return uint32(n);\n }\n\n function safe96(uint n,
        string memory errorMessage) internal pure returns (uint96) {\n require(n \u003c 2**96, errorMessage);\n return uint96(n);\n }\n\n
         function add96(uint96 a, uint96 b, string memory errorMessage) internal pure returns (uint96) {\n uint96 c = a + b;\n require(c
        \u003e= a, errorMessage);\n return c;\n }\n\n function sub96(uint96 a, uint96 b, string memory errorMessage) internal pure returns
        (uint96) {\n require(b \u003c= a, errorMessage);\n return a - b;\n }\n\n function getChainId() internal pure returns (uint) {\n
         uint256 chainId;\n assembly { chainId := chainid() }\n return chainId;\n }\n}\n"},"SafeMath.sol":{"content":"// SPDX
        -License-Identifier: MIT\n\npragma solidity \u003e=0.6.0 \u003c0.8.0;\n\n/**\n * @dev Wrappers over Solidity\u0027s arithmetic operations with
        added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers
        usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores
        this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations
        eliminates an entire\n * class of bugs, so it\u0027s recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the
        addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256
        b) internal pure returns (bool, uint256) {\n uint256 c = a + b;\n if (c \u003c a) return (false, 0);\n return (true, c);\n
        }\n\n /**\n * @dev Returns the substraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n
        */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n if (b \u003e a) return (false, 0);\n return
        (true, a - b);\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n *
        _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n // Gas optimization:
        this is cheaper than requiring \u0027a\u0027 not being zero, but the\n // benefit is lost if \u0027b\u0027 is also tested.\n // See:
        https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) return (true, 0);\n uint256 c = a * b;\n if (c /
        a != b) return (false, 0);\n return (true, c);\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division
        by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n
         if (b == 0) return (false, 0);\n return (true, a / b);\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned
        integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure
        returns (bool, uint256) {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n\n /**\n * @dev Returns the
        addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity\u0027s `+` operator.\n *\n *
        Requirements:\n *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n
         uint256 c = a + b;\n require(c \u003e= a, \"SafeMath: addition overflow\");\n return c;\n }\n\n /**\n * @dev Returns the
        subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity\u0027s `
        -` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal
        pure returns (uint256) {\n require(b \u003c= a, \"SafeMath: subtraction overflow\");\n return a - b;\n }\n\n /**\n * @dev
        Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity\u0027s `*` operator.\n
         *\n * Requirements:\n *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure
        returns (uint256) {\n if (a == 0) return 0;\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\"
        );\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero.
        The result is rounded towards zero.\n *\n * Counterpart to Solidity\u0027s `/` operator. Note: this function uses a\n * `revert` opcode
        (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n *
        Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n
         require(b \u003e 0, \"SafeMath: division by zero\");\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing
        two unsigned integers. (unsigned integer modulo),\n * reverting when dividing by zero.\n *\n * Counterpart to Solidity\u0027s `%`
        operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to
        revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod
        (uint256 a, uint256 b) internal pure returns (uint256) {\n require(b \u003e 0, \"SafeMath: modulo by zero\");\n return a % b;\n
        }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is
        negative).\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily.
        For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity\u0027s `-` operator.\n *\n * Requirements:\n *\n *
        - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n
         require(b \u003c= a, errorMessage);\n return a - b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers
        , reverting with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * CAUTION: This function is
        deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryDiv}.\n *\n
         * Counterpart to Solidity\u0027s `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while
        Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot
        be zero.\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b \u003e 0
        , errorMessage);\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer
        modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires
        allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\n *\n * Counterpart to
        Solidity\u0027s `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n *
        invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n
        function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b \u003e 0, errorMessage);\n
         return a % b;\n }\n}\n"}}
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX