Skip to main content
PulseScanner.io

Address

0x604ac422ee036ffd6ff82d3ffa36ef8ee6032d22
Current Holdings
$0.00
TXs sent
not counted
First Active
2026-02-24
block 25,874,151
Last Active
206 days ago
block 25,877,213
Funded By
not identified

Net worth historyi

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

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

// ─────────────────────────────────────────────
// mmSATS Token
// 1 token = 1 satoshi-like unit
// 21 trillion total supply (21,000,000,000,000)
// ─────────────────────────────────────────────

contract MMSATS is ERC20 {
    uint256 public constant TOTAL_SUPPLY = 21_000_000_000_000;

    constructor() ERC20("mmSATS", "mmSATS") {
        _mint(msg.sender, TOTAL_SUPPLY);
    }

    // No decimals → whole numbers only
    function decimals() public pure override returns (uint8) {
        return 0;
    }
}

// ─────────────────────────────────────────────
// mmSATS Vault (MMSATSReserve)
// 1 WBTC unit (1 sat) = 1 mmSATS
// Deposit: any amount allowed
// Redeem: minimum 1 full WBTC (1e8 units)
// ─────────────────────────────────────────────

contract MMSATSReserve is Ownable, ReentrancyGuard {
    using SafeERC20 for IERC20;

    IERC20 public immutable wbtc;
    IERC20 public immutable mmSATS;

    bool public paused;

    // Minimum redeem = 1.00000000 WBTC = 100_000_000 units (8 decimals)
    uint256 public constant MIN_REDEEM_WBTC = 100_000_000;

    event Deposited(address indexed user, uint256 wbtcAmount);
    event Redeemed(address indexed user, uint256 mmSATSAmount, uint256 wbtcAmount);

    constructor(address _wbtc, address _mmSATS) Ownable(msg.sender) {
        wbtc = IERC20(_wbtc);
        mmSATS = IERC20(_mmSATS);

        require(
            mmSATS.totalSupply() == 21_000_000_000_000,
            "Invalid mmSATS supply"
        );
    }

    modifier whenNotPaused() {
        require(!paused, "Vault is paused");
        _;
    }

    // ── Deposit: any WBTC amount → equal mmSATS
    function deposit(uint256 wbtcAmount)
        external
        nonReentrant
        whenNotPaused
    {
        require(wbtcAmount > 0, "Amount must be > 0");

        require(
            mmSATS.balanceOf(address(this)) >= wbtcAmount,
            "Insufficient mmSATS in vault"
        );

        wbtc.safeTransferFrom(msg.sender, address(this), wbtcAmount);
        mmSATS.safeTransfer(msg.sender, wbtcAmount);

        emit Deposited(msg.sender, wbtcAmount);
    }

    // ── Redeem: mmSATS → WBTC, but minimum 1 full WBTC
    function redeem(uint256 mmSATSAmount)
        external
        nonReentrant
        whenNotPaused
    {
        require(mmSATSAmount > 0, "Amount must be > 0");

        // Enforce minimum redeem size: 1 WBTC = 100_000_000 units
        require(mmSATSAmount >= MIN_REDEEM_WBTC, "Redeem amount too small - minimum 1 WBTC");

        require(
            wbtc.balanceOf(address(this)) >= mmSATSAmount,
            "Insufficient WBTC reserves"
        );

        mmSATS.safeTransferFrom(msg.sender, address(this), mmSATSAmount);
        wbtc.safeTransfer(msg.sender, mmSATSAmount);

        emit Redeemed(msg.sender, mmSATSAmount, mmSATSAmount);
    }

    // ── Owner Controls
    function pause() external onlyOwner {
        paused = true;
    }

    function unpause() external onlyOwner {
        paused = false;
    }

    // ── View Helpers
    function vaultMMSATSBalance() external view returns (uint256) {
        return mmSATS.balanceOf(address(this));
    }

    function vaultWBTCBalance() external view returns (uint256) {
        return wbtc.balanceOf(address(this));
    }

    function circulatingMMSATS() external view returns (uint256) {
        return mmSATS.totalSupply() - mmSATS.balanceOf(address(this));
    }

    function minRedeemAmount() external pure returns (uint256) {
        return MIN_REDEEM_WBTC;
    }
}