Skip to main content
PulseScanner.io

Address

0xdf376b474fd9d9fcc06fd630716b532fbd4342ce
Current Holdings
$0.00
TXs sent
not counted
First Active
2026-01-02
block 25,421,495
Last Active
256 days ago
block 25,423,194
Funded By
not identified

Net worth historyi

No net-worth snapshots recorded yet
exact matchFoodWalletsolc 0.8.20+commit.a1b79de6runtime exact · creation exact
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

contract FoodWallet is ERC721URIStorage, Ownable {
    IERC20 public immutable backingToken;

    uint256 private _nextTokenId;
    mapping(uint256 => uint256) public lockedAmount;

    event Minted(uint256 indexed tokenId, address indexed to, uint256 amount, string uri);
    event Redeemed(uint256 indexed tokenId, address indexed from, uint256 amount);
    event ToppedUp(uint256 indexed tokenId, address indexed from, uint256 amount);

    constructor(address _backingToken)
        ERC721("FoodWallet", "FW")
        Ownable(msg.sender)
    {
        require(_backingToken != address(0), "Invalid token");
        backingToken = IERC20(_backingToken);
    }

    function mintWithCoins(uint256 amount, string calldata tokenUri)
        external
        returns (uint256 tokenId)
    {
        require(amount > 0, "Amount zero");

        tokenId = _nextTokenId++;
        _safeMint(msg.sender, tokenId);
        _setTokenURI(tokenId, tokenUri);

        backingToken.transferFrom(msg.sender, address(this), amount);
        lockedAmount[tokenId] = amount;

        emit Minted(tokenId, msg.sender, amount, tokenUri);
    }

    function redeem(uint256 tokenId) external {
        require(ownerOf(tokenId) == msg.sender, "Not owner");

        uint256 amount = lockedAmount[tokenId];
        require(amount > 0, "Nothing locked");

        lockedAmount[tokenId] = 0;
        _burn(tokenId);

        backingToken.transfer(msg.sender, amount);

        emit Redeemed(tokenId, msg.sender, amount);
    }

    function addCoins(uint256 tokenId, uint256 amount) external {
        require(ownerOf(tokenId) != address(0), "Token burned");
        require(amount > 0, "Amount zero");

        backingToken.transferFrom(msg.sender, address(this), amount);
        lockedAmount[tokenId] += amount;

        emit ToppedUp(tokenId, msg.sender, amount);
    }

    // Owner safety function
    function withdrawTokens(uint256 amount) external onlyOwner {
        backingToken.transfer(owner(), amount);
    }

    // Required override for ERC721URIStorage
    function tokenURI(uint256 tokenId)
        public
        view
        override
        returns (string memory)
    {
        return super.tokenURI(tokenId);
    }
}