Address Details
contract

0xe4aa0f414725C9322a1a9D80d469c5e234786653

Contract Name
MultiFaucet
Creator
0x9c95b0–8c1585 at 0x265e28–2f28f9
Balance
0 CELO ( )
Locked CELO Balance
0.00 CELO
Voting CELO Balance
0.00 CELO
Pending Unlocked Gold
0.00 CELO
Tokens
Fetching tokens...
Transactions
16 Transactions
Transfers
33 Transfers
Gas Used
729,402
Last Balance Update
14618506
This contract has been verified via Sourcify. View contract in Sourcify repository
Contract name:
MultiFaucet




Optimization enabled
true
Compiler version
v0.8.9+commit.e5eed63a




Optimization runs
200
EVM Version
london




Verified at
2023-01-27T02:16:55.124391Z

contracts/Faucet.sol

//SPDX-License-Identifier: AGPL-3.0-or-later

pragma solidity ^0.8.0;
pragma abicoder v2;

import "./interfaces/IERC20Basic.sol";
import "@uniswap/v3-periphery/contracts/libraries/TransferHelper.sol";

/**
 * @title Think and Dev Faucet
 * @author Think and Dev Team
 * @notice Multiple ERC20 faucet
 */
contract MultiFaucet {
    struct Faucet {
        address owner;
        uint256 amountToGive;
    }

    mapping(address => Faucet) public faucets;

    modifier onlyOwner(address _token) {
        require(msg.sender == faucets[_token].owner, "MultiFaucet: You are not the owner of this faucet");
        _;
    }

    /**
     * Add a new faucet to the faucets mapping.
     * @param _token ERC20 token address.
     * @param _amountToGive amount that the faucet will give.
     */
    function addFaucet(address _token, uint256 _amountToGive) external {
        require(
            faucets[_token].owner == address(0),
            "MultiFaucet: This faucet already exist, you can still deposit funds"
        );
        faucets[_token] = Faucet(msg.sender, _amountToGive);
    }

    /**
     * Update the amountToGive to a faucet. Only the faucet owner can perform this action.
     * @param _token ERC20 token address.
     * @param _amountToGive new amount that the faucet will give.
     */
    function updateFaucet(address _token, uint256 _amountToGive) external onlyOwner(_token) {
        faucets[_token].amountToGive = _amountToGive;
    }

    /**
     * Remove a faucet from the faucets mapping. Only the faucet owner can perform this action.
     * @param _token ERC20 token address.
     */
    function removeFaucet(address _token) external onlyOwner(_token) {
        uint256 faucetBalance = IERC20Basic(_token).balanceOf(address(this));
        TransferHelper.safeTransfer(_token, msg.sender, faucetBalance);
        delete faucets[_token];
    }

    /**
     * Gives to the msg.sender the amount of funds specified in amountToGive
     * @param _token ERC20 token address.
     */
    function requestFunds(address _token) external {
        require(faucets[_token].amountToGive != 0, "MultiFaucet: This faucet does not exist");
        uint256 faucetBalance = IERC20Basic(_token).balanceOf(address(this));
        require(faucetBalance >= faucets[_token].amountToGive, "MultiFaucet: This faucet does not have enough funds");
        TransferHelper.safeTransfer(_token, msg.sender, faucets[_token].amountToGive);
    }
}
        

/_openzeppelin/contracts/token/ERC20/IERC20.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
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 amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

    /**
     * @dev Moves `amount` 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 amount) 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 `amount` 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 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` 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 amount
    ) external returns (bool);
}
          

/_uniswap/v3-periphery/contracts/libraries/TransferHelper.sol

// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.6.0;

import '@openzeppelin/contracts/token/ERC20/IERC20.sol';

library TransferHelper {
    /// @notice Transfers tokens from the targeted address to the given destination
    /// @notice Errors with 'STF' if transfer fails
    /// @param token The contract address of the token to be transferred
    /// @param from The originating address from which the tokens will be transferred
    /// @param to The destination address of the transfer
    /// @param value The amount to be transferred
    function safeTransferFrom(
        address token,
        address from,
        address to,
        uint256 value
    ) internal {
        (bool success, bytes memory data) =
            token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'STF');
    }

    /// @notice Transfers tokens from msg.sender to a recipient
    /// @dev Errors with ST if transfer fails
    /// @param token The contract address of the token which will be transferred
    /// @param to The recipient of the transfer
    /// @param value The value of the transfer
    function safeTransfer(
        address token,
        address to,
        uint256 value
    ) internal {
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transfer.selector, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'ST');
    }

    /// @notice Approves the stipulated contract to spend the given allowance in the given token
    /// @dev Errors with 'SA' if transfer fails
    /// @param token The contract address of the token to be approved
    /// @param to The target of the approval
    /// @param value The amount of the given token the target will be allowed to spend
    function safeApprove(
        address token,
        address to,
        uint256 value
    ) internal {
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.approve.selector, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'SA');
    }

    /// @notice Transfers ETH to the recipient address
    /// @dev Fails with `STE`
    /// @param to The destination of the transfer
    /// @param value The value to be transferred
    function safeTransferETH(address to, uint256 value) internal {
        (bool success, ) = to.call{value: value}(new bytes(0));
        require(success, 'STE');
    }
}
          

/contracts/interfaces/IERC20Basic.sol

//SPDX-License-Identifier: AGPL-3.0-or-later

pragma solidity ^0.8.0;

/**
 * @title ERC20Basic
 * @dev Simpler version of ERC20 interface
 */
interface IERC20Basic {
    function transferFrom(
        address from,
        address to,
        uint256 value
    ) external returns (bool);

    function balanceOf(address account) external view returns (uint256);

    event Transfer(address indexed from, address indexed to, uint256 value);
}
          

Contract ABI

[{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addFaucet","inputs":[{"type":"address","name":"_token","internalType":"address"},{"type":"uint256","name":"_amountToGive","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"owner","internalType":"address"},{"type":"uint256","name":"amountToGive","internalType":"uint256"}],"name":"faucets","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"removeFaucet","inputs":[{"type":"address","name":"_token","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"requestFunds","inputs":[{"type":"address","name":"_token","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateFaucet","inputs":[{"type":"address","name":"_token","internalType":"address"},{"type":"uint256","name":"_amountToGive","internalType":"uint256"}]}]
              

Contract Creation Code

0x608060405234801561001057600080fd5b50610746806100206000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c806307229f141461005c578063435d7d8714610071578063544c7cf9146100c757806390f534ce146100da578063bd3f756e146100ed575b600080fd5b61006f61006a3660046105fd565b610100565b005b6100a461007f3660046105fd565b600060208190529081526040902080546001909101546001600160a01b039091169082565b604080516001600160a01b03909316835260208301919091520160405180910390f35b61006f6100d53660046105fd565b6101f8565b61006f6100e836600461061f565b6103a1565b61006f6100fb36600461061f565b610486565b6001600160a01b0381811660009081526020819052604090205482911633146101445760405162461bcd60e51b815260040161013b90610649565b60405180910390fd5b6040516370a0823160e01b81523060048201526000906001600160a01b038416906370a082319060240160206040518083038186803b15801561018657600080fd5b505afa15801561019a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101be919061069a565b90506101cb8333836104e1565b50506001600160a01b0316600090815260208190526040812080546001600160a01b031916815560010155565b6001600160a01b0381166000908152602081905260409020600101546102705760405162461bcd60e51b815260206004820152602760248201527f4d756c74694661756365743a20546869732066617563657420646f6573206e6f6044820152661d08195e1a5cdd60ca1b606482015260840161013b565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a082319060240160206040518083038186803b1580156102b257600080fd5b505afa1580156102c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102ea919061069a565b6001600160a01b0383166000908152602081905260409020600101549091508110156103745760405162461bcd60e51b815260206004820152603360248201527f4d756c74694661756365743a20546869732066617563657420646f6573206e6f60448201527274206861766520656e6f7567682066756e647360681b606482015260840161013b565b6001600160a01b03821660009081526020819052604090206001015461039d90839033906104e1565b5050565b6001600160a01b03828116600090815260208190526040902054161561043b5760405162461bcd60e51b815260206004820152604360248201527f4d756c74694661756365743a20546869732066617563657420616c726561647960448201527f2065786973742c20796f752063616e207374696c6c206465706f7369742066756064820152626e647360e81b608482015260a40161013b565b60408051808201825233815260208082019384526001600160a01b0394851660009081529081905291909120905181546001600160a01b031916931692909217825551600190910155565b6001600160a01b0382811660009081526020819052604090205483911633146104c15760405162461bcd60e51b815260040161013b90610649565b506001600160a01b03909116600090815260208190526040902060010155565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b179052915160009283929087169161053d91906106b3565b6000604051808303816000865af19150503d806000811461057a576040519150601f19603f3d011682016040523d82523d6000602084013e61057f565b606091505b50915091508180156105a95750805115806105a95750808060200190518101906105a991906106ee565b6105da5760405162461bcd60e51b815260206004820152600260248201526114d560f21b604482015260640161013b565b5050505050565b80356001600160a01b03811681146105f857600080fd5b919050565b60006020828403121561060f57600080fd5b610618826105e1565b9392505050565b6000806040838503121561063257600080fd5b61063b836105e1565b946020939093013593505050565b60208082526031908201527f4d756c74694661756365743a20596f7520617265206e6f7420746865206f776e604082015270195c881bd9881d1a1a5cc819985d58d95d607a1b606082015260800190565b6000602082840312156106ac57600080fd5b5051919050565b6000825160005b818110156106d457602081860181015185830152016106ba565b818111156106e3576000828501525b509190910192915050565b60006020828403121561070057600080fd5b8151801515811461061857600080fdfea2646970667358221220dba56abb2cdc282e7b5e705ee0c07db6a1f21793c7c9b41ab9a15fc1c7ff881964736f6c63430008090033

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106100575760003560e01c806307229f141461005c578063435d7d8714610071578063544c7cf9146100c757806390f534ce146100da578063bd3f756e146100ed575b600080fd5b61006f61006a3660046105fd565b610100565b005b6100a461007f3660046105fd565b600060208190529081526040902080546001909101546001600160a01b039091169082565b604080516001600160a01b03909316835260208301919091520160405180910390f35b61006f6100d53660046105fd565b6101f8565b61006f6100e836600461061f565b6103a1565b61006f6100fb36600461061f565b610486565b6001600160a01b0381811660009081526020819052604090205482911633146101445760405162461bcd60e51b815260040161013b90610649565b60405180910390fd5b6040516370a0823160e01b81523060048201526000906001600160a01b038416906370a082319060240160206040518083038186803b15801561018657600080fd5b505afa15801561019a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101be919061069a565b90506101cb8333836104e1565b50506001600160a01b0316600090815260208190526040812080546001600160a01b031916815560010155565b6001600160a01b0381166000908152602081905260409020600101546102705760405162461bcd60e51b815260206004820152602760248201527f4d756c74694661756365743a20546869732066617563657420646f6573206e6f6044820152661d08195e1a5cdd60ca1b606482015260840161013b565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a082319060240160206040518083038186803b1580156102b257600080fd5b505afa1580156102c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102ea919061069a565b6001600160a01b0383166000908152602081905260409020600101549091508110156103745760405162461bcd60e51b815260206004820152603360248201527f4d756c74694661756365743a20546869732066617563657420646f6573206e6f60448201527274206861766520656e6f7567682066756e647360681b606482015260840161013b565b6001600160a01b03821660009081526020819052604090206001015461039d90839033906104e1565b5050565b6001600160a01b03828116600090815260208190526040902054161561043b5760405162461bcd60e51b815260206004820152604360248201527f4d756c74694661756365743a20546869732066617563657420616c726561647960448201527f2065786973742c20796f752063616e207374696c6c206465706f7369742066756064820152626e647360e81b608482015260a40161013b565b60408051808201825233815260208082019384526001600160a01b0394851660009081529081905291909120905181546001600160a01b031916931692909217825551600190910155565b6001600160a01b0382811660009081526020819052604090205483911633146104c15760405162461bcd60e51b815260040161013b90610649565b506001600160a01b03909116600090815260208190526040902060010155565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b179052915160009283929087169161053d91906106b3565b6000604051808303816000865af19150503d806000811461057a576040519150601f19603f3d011682016040523d82523d6000602084013e61057f565b606091505b50915091508180156105a95750805115806105a95750808060200190518101906105a991906106ee565b6105da5760405162461bcd60e51b815260206004820152600260248201526114d560f21b604482015260640161013b565b5050505050565b80356001600160a01b03811681146105f857600080fd5b919050565b60006020828403121561060f57600080fd5b610618826105e1565b9392505050565b6000806040838503121561063257600080fd5b61063b836105e1565b946020939093013593505050565b60208082526031908201527f4d756c74694661756365743a20596f7520617265206e6f7420746865206f776e604082015270195c881bd9881d1a1a5cc819985d58d95d607a1b606082015260800190565b6000602082840312156106ac57600080fd5b5051919050565b6000825160005b818110156106d457602081860181015185830152016106ba565b818111156106e3576000828501525b509190910192915050565b60006020828403121561070057600080fd5b8151801515811461061857600080fdfea2646970667358221220dba56abb2cdc282e7b5e705ee0c07db6a1f21793c7c9b41ab9a15fc1c7ff881964736f6c63430008090033