Cryo Explorer Ethereum Mainnet

Address Contract Verified

Address 0x000000000CBDC84a73055389D392710263Bb31e7
Balance 0 ETH
Nonce 1
Code Size 4230 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

4230 bytes
0x608060405234801561001057600080fd5b506004361061010b5760003560e01c80636b2b674b116100a257806388ead3b81161007157806388ead3b81461028c5780638da5cb5b1461029f578063b215a130146102b0578063eef21cd2146102d0578063f2fde38b146102e357600080fd5b80636b2b674b14610212578063715018a6146102255780637ac07dcc1461022d5780637bbf4a3f1461026957600080fd5b8063485cc955116100de578063485cc9551461019457806349c0f07f146101a757806355a373d6146101c757806365e61fc3146101f257600080fd5b8063073a56e114610110578063218d4793146101365780632b603c711461015f57806340c10f191461017f575b600080fd5b61012361011e366004610e6b565b6102f6565b6040519081526020015b60405180910390f35b610123610144366004610e6b565b6001600160a01b031660009081526005602052604090205490565b61012361016d366004610e6b565b60056020526000908152604090205481565b61019261018d366004610eb9565b61032a565b005b6101926101a2366004610e86565b610579565b6101236101b5366004610e6b565b60036020526000908152604090205481565b6006546101da906001600160a01b031681565b6040516001600160a01b03909116815260200161012d565b610123610200366004610e6b565b60046020526000908152604090205481565b610123610220366004610e6b565b61071b565b610192610742565b61025961023b366004610e6b565b6001600160a01b031660009081526001602052604090205460ff1690565b604051901515815260200161012d565b610259610277366004610e6b565b60016020526000908152604090205460ff1681565b61019261029a366004610ee3565b610778565b6000546001600160a01b03166101da565b6101236102be366004610e6b565b60026020526000908152604090205481565b6101926102de366004610e6b565b610931565b6101926102f1366004610e6b565b6109a4565b600061030182610a3f565b6001600160a01b0383166000908152600560205260409020546103249190610f9a565b92915050565b3360009081526001602052604090205460ff1661039a5760405162461bcd60e51b8152602060048201526024808201527f526174654c696d69743a2063616c6c6572206973206e6f742077686974656c696044820152631cdd195960e21b60648201526084015b60405180910390fd5b6001600160a01b0382166104075760405162461bcd60e51b815260206004820152602e60248201527f4d696e74466f727761726465723a2063616e6e6f74206d696e7420746f20746860448201526d65207a65726f206164647265737360901b6064820152608401610391565b6000811161046d5760405162461bcd60e51b815260206004820152602d60248201527f4d696e74466f727761726465723a206d696e7420616d6f756e74206e6f74206760448201526c0726561746572207468616e203609c1b6064820152608401610391565b61047633610b26565b336000908152600560205260409020548111156104f15760405162461bcd60e51b815260206004820152603360248201527f4d696e74466f727761726465723a206d696e7420616d6f756e7420657863656560448201527264732063616c6c657220616c6c6f77616e636560681b6064820152608401610391565b3360009081526005602052604090205461050c908290610ff3565b3360009081526005602052604090205560065461053590839083906001600160a01b0316610bf8565b6040518181526001600160a01b0383169033907fab8530f87dc9b59234c4623bf917212bb2536d647574c8e7e5da92c2ede0c9f89060200160405180910390a35050565b6000546001600160a01b031633146105a35760405162461bcd60e51b815260040161039190610f65565b600654600160a01b900460ff16156106145760405162461bcd60e51b815260206004820152602e60248201527f4d696e74466f727761726465723a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610391565b6001600160a01b03821661067b5760405162461bcd60e51b815260206004820152602860248201527f4d696e74466f727761726465723a206f776e657220697320746865207a65726f604482015267206164647265737360c01b6064820152608401610391565b6001600160a01b0381166106ea5760405162461bcd60e51b815260206004820152603060248201527f4d696e74466f727761726465723a20746f6b656e436f6e74726163742069732060448201526f746865207a65726f206164647265737360801b6064820152608401610391565b6106f3826109a4565b600680546001600160a81b0319166001600160a01b0390921691909117600160a01b17905550565b600061072682610b26565b506001600160a01b031660009081526005602052604090205490565b6000546001600160a01b0316331461076c5760405162461bcd60e51b815260040161039190610f65565b6107766000610c85565b565b6000546001600160a01b031633146107a25760405162461bcd60e51b815260040161039190610f65565b6001600160a01b0383166108065760405162461bcd60e51b815260206004820152602560248201527f526174654c696d69743a2063616c6c657220697320746865207a65726f206164604482015264647265737360d81b6064820152608401610391565b600082116108565760405162461bcd60e51b815260206004820152601960248201527f526174654c696d69743a20616d6f756e74206973207a65726f000000000000006044820152606401610391565b600081116108a65760405162461bcd60e51b815260206004820152601b60248201527f526174654c696d69743a20696e74657276616c206973207a65726f00000000006044820152606401610391565b6001600160a01b0383166000818152600160208181526040808420805460ff1916909317909255600581528183208690556004815281832086905560038152818320429055600281529181902084905580518581529182018490527fd471a172f23699e5022a18bcbb4025d085f6ca049fa7411510eac07e9a152512910160405180910390a2505050565b6000546001600160a01b0316331461095b5760405162461bcd60e51b815260040161039190610f65565b6001600160a01b038116600081815260016020526040808220805460ff19169055517f50c35a67b454d38c20800d5b55e320f58f4c9c86a28d8ab20f03045d1a38d99a9190a250565b6000546001600160a01b031633146109ce5760405162461bcd60e51b815260040161039190610f65565b6001600160a01b038116610a335760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610391565b610a3c81610c85565b50565b6001600160a01b0381166000908152600360205260408120548190610a649042610ff3565b6001600160a01b03841660009081526002602090815260408083205460049092528220549293509091610a979084610fd4565b610aa19190610fb2565b6001600160a01b03851660009081526005602052604081205491925090610ac9908390610f9a565b6001600160a01b038616600090815260046020526040902054909150811115610b1e576001600160a01b038516600090815260056020908152604080832054600490925290912054610b1b9190610ff3565b91505b509392505050565b6001600160a01b0381166000908152600460209081526040808320546005909252909120541415610b545750565b6000610b5f82610a3f565b905080610b6a575050565b6001600160a01b038216600090815260056020526040902054610b8e908290610f9a565b6001600160a01b038316600081815260056020818152604080842095865560038252928390204290559081529254815190815292830184905290917f37c856889da73e6bbe7d58cd39546fc6619ef62cbad51f4acbad45d6b7247fa0910160405180910390a25050565b604080516001600160a01b038516602482015260448082018590528251808303909101815260649091018252602080820180516001600160e01b03166340c10f1960e01b1790528251808401909352601783527f4d696e7465725574696c3a206d696e74206661696c65640000000000000000009083015290610c7e9083908390610cd5565b5050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060610ce48484600085610cee565b90505b9392505050565b606082471015610d4f5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610391565b843b610d9d5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610391565b600080866001600160a01b03168587604051610db99190610f16565b60006040518083038185875af1925050503d8060008114610df6576040519150601f19603f3d011682016040523d82523d6000602084013e610dfb565b606091505b5091509150610e0b828286610e16565b979650505050505050565b60608315610e25575081610ce7565b825115610e355782518084602001fd5b8160405162461bcd60e51b81526004016103919190610f32565b80356001600160a01b0381168114610e6657600080fd5b919050565b600060208284031215610e7d57600080fd5b610ce782610e4f565b60008060408385031215610e9957600080fd5b610ea283610e4f565b9150610eb060208401610e4f565b90509250929050565b60008060408385031215610ecc57600080fd5b610ed583610e4f565b946020939093013593505050565b600080600060608486031215610ef857600080fd5b610f0184610e4f565b95602085013595506040909401359392505050565b60008251610f2881846020870161100a565b9190910192915050565b6020815260008251806020840152610f5181604085016020870161100a565b601f01601f19169190910160400192915050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60008219821115610fad57610fad61103a565b500190565b600082610fcf57634e487b7160e01b600052601260045260246000fd5b500490565b6000816000190483118215151615610fee57610fee61103a565b500290565b6000828210156110055761100561103a565b500390565b60005b8381101561102557818101518382015260200161100d565b83811115611034576000848401525b50505050565b634e487b7160e01b600052601160045260246000fdfea2646970667358221220374fa72f9c67b1d523e87d9ea9904064208736c328599362cf1a21b88f0184bf64736f6c63430008060033

Verified Source Code Full Match

Compiler: v0.8.6+commit.11564f7e EVM: berlin Optimization: Yes (200 runs)
MintUtil.sol 45 lines
/**
 * SPDX-License-Identifier: MIT
 *
 * Copyright (c) 2021 Coinbase, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
pragma solidity 0.8.6;

import {Address} from "@openzeppelin4.2.0/contracts/utils/Address.sol";

/**
 * @notice MintUtil
 * @dev Used for safe minting.
 */
library MintUtil {
    bytes4 private constant _MINT_SELECTOR = bytes4(keccak256("mint(address,uint256)"));

    /**
     * @notice Safely mints ERC20 token.
     * @param to Recipient's address
     * @param value Amount to mint
     * @param tokenContract Token contract address
     */
    function safeMint(address to, uint256 value, address tokenContract) internal {
        bytes memory data = abi.encodeWithSelector(_MINT_SELECTOR, to, value);
        Address.functionCall(tokenContract, data, "MinterUtil: mint failed");
    }
}
RateLimit.sol 145 lines
/**
 * SPDX-License-Identifier: MIT
 *
 * Copyright (c) 2021 Coinbase, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
pragma solidity 0.8.6;

import {Ownable} from "@openzeppelin4.2.0/contracts/access/Ownable.sol";

/**
 * @title RateLimit
 * @dev Rate limiting contract for function calls
 */
contract RateLimit is Ownable {
    mapping(address => bool) public callers;
    mapping(address => uint256) public intervals;
    mapping(address => uint256) public allowancesLastSet;
    mapping(address => uint256) public maxAllowances;
    mapping(address => uint256) public allowances;

    event CallerConfigured(address indexed caller, uint256 amount, uint256 interval);
    event CallerRemoved(address indexed caller);
    event AllowanceReplenished(address indexed caller, uint256 allowance, uint256 amountReplenished);

    /**
     * @dev Throws if called by any account other than a caller.
     * Rate limited functionality in inheriting contracts must have the only caller modifier
     */
    modifier onlyCallers() {
        require(callers[msg.sender], "RateLimit: caller is not whitelisted");
        _;
    }

    /**
     * @dev Function to add/update a new caller. Also updates allowancesLastSet for that caller.
     * @param caller The address of the caller
     * @param amount The call amount allowed for the caller for a given interval
     * @param interval The interval for a given caller
     */
    function configureCaller(address caller, uint256 amount, uint256 interval) external onlyOwner {
        require(caller != address(0), "RateLimit: caller is the zero address");
        require(amount > 0, "RateLimit: amount is zero");
        require(interval > 0, "RateLimit: interval is zero");
        callers[caller] = true;
        maxAllowances[caller] = allowances[caller] = amount;
        allowancesLastSet[caller] = block.timestamp;
        intervals[caller] = interval;
        emit CallerConfigured(caller, amount, interval);
    }

    /**
     * @dev Function to remove a caller.
     * @param caller The address of the caller
     */
    function removeCaller(address caller) external onlyOwner {
        callers[caller] = false;
        emit CallerRemoved(caller);
    }

    /**
     * @dev Get the stored caller allowance for an account
     * @param caller The address of the caller
     */
    function allowanceStored(address caller) external view returns (uint256) {
        return allowances[caller];
    }

    /**
     * @dev Checks if account is a caller
     * @param account The address to check
     */
    function isCaller(address account) external view returns (bool) {
        return callers[account];
    }

    /**
     * @dev Helper function to calculate the estimated allowance given caller address
     * @param caller The address whose call allowance is being estimated
     */
    function estimatedAllowance(address caller) external view returns (uint256) {
        return allowances[caller] + _getReplenishAmount(caller);
    }

    /**
     * @dev Get the current caller allowance for an account
     * @param caller The address of the caller
     */
    function allowanceCurrent(address caller) public returns (uint256) {
        _replenishAllowance(caller);
        return allowances[caller];
    }

    /**
     * @dev Helper function to replenish a caller's allowance over the interval in proportion to time elapsed, up to
     * their maximum allowance
     * @param caller The address whose allowance is being updated
     */
    function _replenishAllowance(address caller) internal {
        if (allowances[caller] == maxAllowances[caller]) {
            return;
        }
        uint256 amountToReplenish = _getReplenishAmount(caller);
        if (amountToReplenish == 0) {
            return;
        }

        allowances[caller] = allowances[caller] + amountToReplenish;
        allowancesLastSet[caller] = block.timestamp;
        emit AllowanceReplenished(caller, allowances[caller], amountToReplenish);
    }

    /**
     * @dev Helper function to calculate the replenishment amount
     * @param caller The address whose allowance is being estimated
     */
    function _getReplenishAmount(address caller) internal view returns (uint256) {
        uint256 secondsSinceAllowanceSet = block.timestamp - allowancesLastSet[caller];

        uint256 amountToReplenish = (secondsSinceAllowanceSet * maxAllowances[caller]) / intervals[caller];
        uint256 allowanceAfterReplenish = allowances[caller] + amountToReplenish;

        if (allowanceAfterReplenish > maxAllowances[caller]) {
            amountToReplenish = maxAllowances[caller] - allowances[caller];
        }
        return amountToReplenish;
    }
}
MintForwarder.sol 72 lines
/**
 * SPDX-License-Identifier: MIT
 *
 * Copyright (c) 2021 Coinbase, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
pragma solidity 0.8.6;

import {MintUtil} from "./MintUtil.sol";
import {RateLimit} from "./RateLimit.sol";

/**
 * @title MintForwarder
 * @dev Forwarding contract to ERC20 tokens with mint functionality
 */
contract MintForwarder is RateLimit {
    address public tokenContract;
    bool internal initialized;

    event Mint(address indexed minter, address indexed to, uint256 amount);

    /**
     * @dev Function to initialize the contract
     * @param newOwner The address of the owner of the mint contract
     * @param newTokenContract The address of the token contract for which this contract mints
     */
    function initialize(address newOwner, address newTokenContract) external onlyOwner {
        require(!initialized, "MintForwarder: contract is already initialized");
        require(newOwner != address(0), "MintForwarder: owner is the zero address");
        require(newTokenContract != address(0), "MintForwarder: tokenContract is the zero address");
        transferOwnership(newOwner);
        tokenContract = newTokenContract;
        initialized = true;
    }

    /**
     * @dev Rate limited function to mint tokens
     *  @param _to The address that will receive the minted tokens.
     * @param _amount The amount of tokens to mint. Must be less than or equal
     * to the allowance of the caller.
     */
    function mint(address _to, uint256 _amount) external onlyCallers {
        require(_to != address(0), "MintForwarder: cannot mint to the zero address");
        require(_amount > 0, "MintForwarder: mint amount not greater than 0");

        _replenishAllowance(msg.sender);

        require(_amount <= allowances[msg.sender], "MintForwarder: mint amount exceeds caller allowance");

        allowances[msg.sender] = allowances[msg.sender] - _amount;

        MintUtil.safeMint(_to, _amount, tokenContract);
        emit Mint(msg.sender, _to, _amount);
    }
}
Address.sol 210 lines
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    function _verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) private pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}
Context.sol 23 lines
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/*
 * @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;
    }
}
Ownable.sol 71 lines
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../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.
 *
 * By default, the owner account will be the one that deploys the contract. 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;

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _setOwner(_msgSender());
    }

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _setOwner(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 {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _setOwner(newOwner);
    }

    function _setOwner(address newOwner) private {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

Read Contract

allowanceStored 0x218d4793 → uint256
allowances 0x2b603c71 → uint256
allowancesLastSet 0x49c0f07f → uint256
callers 0x7bbf4a3f → bool
estimatedAllowance 0x073a56e1 → uint256
intervals 0xb215a130 → uint256
isCaller 0x7ac07dcc → bool
maxAllowances 0x65e61fc3 → uint256
owner 0x8da5cb5b → address
tokenContract 0x55a373d6 → address

Write Contract 7 functions

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

allowanceCurrent 0x6b2b674b
address caller
returns: uint256
configureCaller 0x88ead3b8
address caller
uint256 amount
uint256 interval
initialize 0x485cc955
address newOwner
address newTokenContract
mint 0x40c10f19
address _to
uint256 _amount
removeCaller 0xeef21cd2
address caller
renounceOwnership 0x715018a6
No parameters
transferOwnership 0xf2fde38b
address newOwner

Recent Transactions

No transactions found for this address