ETH Price: $3,063.04 (+1.23%)
Gas: 6 Gwei

Contract

0x31dBa5404304C465c198Aa7b8092280516D07624
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Value
0x60806040132571312021-09-19 16:10:141024 days ago1632067814IN
 Create: MagicMintReentrancyFix
0 ETH0.0115818552.10243393

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
MagicMintReentrancyFix

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 7 : MagicMintReentrancyFix.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import '@solidstate/contracts/token/ERC20/base/ERC20BaseInternal.sol';
import '@solidstate/contracts/utils/ReentrancyGuard.sol';

import './MagicWhitelistStorage.sol';

contract MagicMintReentrancyFix is ERC20BaseInternal, ReentrancyGuard {
    function mint(address account, uint256 amount) external nonReentrant {
        require(
            MagicWhitelistStorage.layout().whitelist[msg.sender],
            'Magic: sender must be whitelisted'
        );
        _mint(account, amount);
    }
}

File 2 of 7 : ERC20BaseInternal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import {IERC20Internal} from '../IERC20Internal.sol';
import {ERC20BaseStorage} from './ERC20BaseStorage.sol';

/**
 * @title Base ERC20 implementation, excluding optional extensions
 */
abstract contract ERC20BaseInternal is IERC20Internal {
  /**
   * @notice query the total minted token supply
   * @return token supply
   */
  function _totalSupply () virtual internal view returns (uint) {
    return ERC20BaseStorage.layout().totalSupply;
  }

  /**
   * @notice query the token balance of given account
   * @param account address to query
   * @return token balance
   */
  function _balanceOf (
    address account
  ) virtual internal view returns (uint) {
    return ERC20BaseStorage.layout().balances[account];
  }

  /**
   * @notice enable spender to spend tokens on behalf of holder
   * @param holder address on whose behalf tokens may be spent
   * @param spender recipient of allowance
   * @param amount quantity of tokens approved for spending
   */
  function _approve (
    address holder,
    address spender,
    uint amount
  ) virtual internal {
    require(holder != address(0), 'ERC20: approve from the zero address');
    require(spender != address(0), 'ERC20: approve to the zero address');

    ERC20BaseStorage.layout().allowances[holder][spender] = amount;

    emit Approval(holder, spender, amount);
  }

  /**
   * @notice mint tokens for given account
   * @param account recipient of minted tokens
   * @param amount quantity of tokens minted
   */
  function _mint (
    address account,
    uint amount
  ) virtual internal {
    require(account != address(0), 'ERC20: mint to the zero address');

    _beforeTokenTransfer(address(0), account, amount);

    ERC20BaseStorage.Layout storage l = ERC20BaseStorage.layout();
    l.totalSupply += amount;
    l.balances[account] += amount;

    emit Transfer(address(0), account, amount);
  }

  /**
   * @notice burn tokens held by given account
   * @param account holder of burned tokens
   * @param amount quantity of tokens burned
   */
  function _burn (
    address account,
    uint amount
  ) virtual internal {
    require(account != address(0), 'ERC20: burn from the zero address');

    _beforeTokenTransfer(account, address(0), amount);

    ERC20BaseStorage.Layout storage l = ERC20BaseStorage.layout();
    uint256 balance = l.balances[account];
    require(balance >= amount, "ERC20: burn amount exceeds balance");
    unchecked {
      l.balances[account] = balance - amount;
    }
    l.totalSupply -= amount;

    emit Transfer(account, address(0), amount);
  }

  /**
   * @notice transfer tokens from holder to recipient
   * @param holder owner of tokens to be transferred
   * @param recipient beneficiary of transfer
   * @param amount quantity of tokens transferred
   */
  function _transfer (
    address holder,
    address recipient,
    uint amount
  ) virtual internal {
    require(holder != address(0), 'ERC20: transfer from the zero address');
    require(recipient != address(0), 'ERC20: transfer to the zero address');

    _beforeTokenTransfer(holder, recipient, amount);

    ERC20BaseStorage.Layout storage l = ERC20BaseStorage.layout();
    uint256 holderBalance = l.balances[holder];
    require(holderBalance >= amount, 'ERC20: transfer amount exceeds balance');
    unchecked {
      l.balances[holder] = holderBalance - amount;
    }
    l.balances[recipient] += amount;

    emit Transfer(holder, recipient, amount);
  }

  /**
   * @notice ERC20 hook, called before all transfers including mint and burn
   * @dev function should be overridden and new implementation must call super
   * @param from sender of tokens
   * @param to receiver of tokens
   * @param amount quantity of tokens transferred
   */
  function _beforeTokenTransfer (
    address from,
    address to,
    uint amount
  ) virtual internal {}
}

File 3 of 7 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import {ReentrancyGuardStorage} from './ReentrancyGuardStorage.sol';

/**
 * @title Utility contract for preventing reentrancy attacks
 */
abstract contract ReentrancyGuard {
  modifier nonReentrant () {
    ReentrancyGuardStorage.Layout storage l = ReentrancyGuardStorage.layout();
    require(l.status != 2, 'ReentrancyGuard: reentrant call');
    l.status = 2;
    _;
    l.status = 1;
  }
}

File 4 of 7 : MagicWhitelistStorage.sol
// SPDX-License-Identifier: UNLICENSED

pragma solidity ^0.8.0;

library MagicWhitelistStorage {
    struct Layout {
        mapping(address => bool) whitelist;
    }

    bytes32 internal constant STORAGE_SLOT =
        keccak256('treasure.contracts.storage.MagicWhitelist');

    function layout() internal pure returns (Layout storage l) {
        bytes32 slot = STORAGE_SLOT;
        assembly {
            l.slot := slot
        }
    }
}

File 5 of 7 : IERC20Internal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @title Partial ERC20 interface needed by internal functions
 */
interface IERC20Internal {
  event Transfer(
    address indexed from,
    address indexed to,
    uint256 value
  );

  event Approval(
    address indexed owner,
    address indexed spender,
    uint256 value
  );
}

File 6 of 7 : ERC20BaseStorage.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

library ERC20BaseStorage {
  struct Layout {
    mapping (address => uint) balances;
    mapping (address => mapping (address => uint)) allowances;
    uint totalSupply;
  }

  bytes32 internal constant STORAGE_SLOT = keccak256(
    'solidstate.contracts.storage.ERC20Base'
  );

  function layout () internal pure returns (Layout storage l) {
    bytes32 slot = STORAGE_SLOT;
    assembly { l.slot := slot }
  }
}

File 7 of 7 : ReentrancyGuardStorage.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

library ReentrancyGuardStorage {
  struct Layout {
    uint status;
  }

  bytes32 internal constant STORAGE_SLOT = keccak256(
    'solidstate.contracts.storage.ReentrancyGuard'
  );

  function layout () internal pure returns (Layout storage l) {
    bytes32 slot = STORAGE_SLOT;
    assembly { l.slot := slot }
  }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405234801561001057600080fd5b5061030e806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c806340c10f1914610030575b600080fd5b61004361003e36600461027e565b610045565b005b7f09acf4e54214992e70883cf7dcd6957ff2c71cd9e14df4bec4383bc0d11607dc8054600214156100bd5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b600281553360009081527f7041ce7c5c869a9d35c22f2295d95baf4e010cb9efcb1a8027a9b11d48a1d53a602052604090205460ff166101495760405162461bcd60e51b815260206004820152602160248201527f4d616769633a2073656e646572206d7573742062652077686974656c697374656044820152601960fa1b60648201526084016100b4565b610153838361015b565b600190555050565b6001600160a01b0382166101b15760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016100b4565b7fc991b2e918acaba8e5721668ed0b1982684e5a8692a621bcd2d7ef326bb015b680547fc991b2e918acaba8e5721668ed0b1982684e5a8692a621bcd2d7ef326bb015b49183916000906102069084906102b4565b90915550506001600160a01b038316600090815260208290526040812080548492906102339084906102b4565b90915550506040518281526001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60008060408385031215610290578182fd5b82356001600160a01b03811681146102a6578283fd5b946020939093013593505050565b600082198211156102d357634e487b7160e01b81526011600452602481fd5b50019056fea26469706673582212209996b0683ca4f870e19770e63d5e8490df6a2a8f167ffadbc1d113c1bfac6cd464736f6c63430008040033

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061002b5760003560e01c806340c10f1914610030575b600080fd5b61004361003e36600461027e565b610045565b005b7f09acf4e54214992e70883cf7dcd6957ff2c71cd9e14df4bec4383bc0d11607dc8054600214156100bd5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b600281553360009081527f7041ce7c5c869a9d35c22f2295d95baf4e010cb9efcb1a8027a9b11d48a1d53a602052604090205460ff166101495760405162461bcd60e51b815260206004820152602160248201527f4d616769633a2073656e646572206d7573742062652077686974656c697374656044820152601960fa1b60648201526084016100b4565b610153838361015b565b600190555050565b6001600160a01b0382166101b15760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016100b4565b7fc991b2e918acaba8e5721668ed0b1982684e5a8692a621bcd2d7ef326bb015b680547fc991b2e918acaba8e5721668ed0b1982684e5a8692a621bcd2d7ef326bb015b49183916000906102069084906102b4565b90915550506001600160a01b038316600090815260208290526040812080548492906102339084906102b4565b90915550506040518281526001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60008060408385031215610290578182fd5b82356001600160a01b03811681146102a6578283fd5b946020939093013593505050565b600082198211156102d357634e487b7160e01b81526011600452602481fd5b50019056fea26469706673582212209996b0683ca4f870e19770e63d5e8490df6a2a8f167ffadbc1d113c1bfac6cd464736f6c63430008040033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.