ETH Price: $2,028.93 (-1.40%)

Transaction Decoder

Block:
19975780 at May-29-2024 01:21:35 PM +UTC
Transaction Fee:
0.001060233532430906 ETH $2.15
Gas Used:
54,799 Gas / 19.347680294 Gwei

Emitted Events:

Account State Difference:

  Address   Before After State Difference Code
0x2fca9628...9dD4cC94B
0.026297348050019319 Eth
Nonce: 108
0.025237114517588413 Eth
Nonce: 109
0.001060233532430906
(beaverbuild)
13.456957229144784261 Eth13.456961430453089852 Eth0.000004201308305591
0x992D3395...da38c66F6

Execution Trace

ERC20Basic.transfer( to=0xf78398c0842C29Fc00C76470340b543EE1B2d162, amount=6000000000000000000000000 ) => ( True )
{"ERC20Basic.sol":{"content":"// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.8.9;\r\n\r\nimport \"./IERC20.sol\";\r\nimport \"./Ownable.sol\";\r\nimport \"./Whitelist.sol\";\r\n\r\n/**\r\n * @title ERC20 Basic.\r\n *\r\n * @dev ERC20 SOUL token.\r\n */\r\ncontract ERC20Basic is IERC20, Ownable, Whitelist {\r\n    string public name = \"SOUL TOKEN\";\r\n    string public symbol = \"SOUL\";\r\n    uint8 public constant decimals = 18;\r\n\r\n    uint256 private _totalSupply = 10000000000000000000000000000 wei;\r\n    mapping(address =\u003e uint256) private _balances;\r\n    mapping(address =\u003e mapping(address =\u003e uint256)) private _allowances;\r\n    mapping(address =\u003e uint256) private _lockedAmount;\r\n\r\n    event Lock(address indexed owner, address account, uint256 amount);\r\n    event Unlock(address indexed owner, address account, uint256 amount);\r\n\r\n    constructor() {\r\n        _balances[msg.sender] = _totalSupply;\r\n    }\r\n\r\n    function totalSupply() public view override returns (uint256) {\r\n        return _totalSupply;\r\n    }\r\n\r\n    function balanceOf(address account) public view override returns (uint256) {\r\n        return _balances[account];\r\n    }\r\n\r\n    function allowance(address owner, address spender) public view override returns (uint256) {\r\n        return _allowances[owner][spender];\r\n    }\r\n\r\n    /**\r\n     * @return The amount of tokens locked to `account`.\r\n     */\r\n    function lockedAmountOf(address account) public view returns (uint256) {\r\n        return _lockedAmount[account];\r\n    }\r\n\r\n    function transfer(address to, uint256 amount) public override returns (bool) {\r\n        _transfer(msg.sender, to, amount);\r\n        return true;\r\n    }\r\n\r\n    /**\r\n     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\r\n     * `transferFrom`. This is semantically equivalent to an infinite approval.\r\n     */\r\n    function approve(address spender, uint256 amount) public override returns (bool) {\r\n        _approve(msg.sender, spender, amount);\r\n        return true;\r\n    }\r\n\r\n    // OPTIONAL\r\n    function transferFrom(address from, address to, uint256 amount) public override returns (bool) {\r\n        _spendAllowance(from, msg.sender, amount);\r\n        _transfer(from, to, amount);\r\n        return true;\r\n    }\r\n\r\n    function _transfer(address from, address to, uint256 amount) internal {\r\n        require(from != address(0), \"ERC20Basic: transfer from the zero address\");\r\n        require(to != address(0), \"ERC20Basic: transfer to the zero address\");\r\n\r\n        uint256 currentBalance = balanceOf(from);\r\n        uint256 lockedAmount = lockedAmountOf(from);\r\n        uint256 availableAmount;\r\n\r\n        require(currentBalance \u003e= lockedAmount);\r\n        unchecked { availableAmount = currentBalance - lockedAmount; }\r\n        require(availableAmount \u003e= amount, \"ERC20Basic: transfer amount exceeds balance\");\r\n\r\n        unchecked {\r\n            _balances[from] -= amount;\r\n            _balances[to] += amount;\r\n            require(_balances[to] \u003e= amount, \"ERC20Basic: overflow of the to\u0027s balance\");\r\n        }\r\n\r\n        emit Transfer(from, to, amount);\r\n    }\r\n\r\n    function _approve(address owner, address spender, uint256 amount) internal {\r\n        require(owner != address(0), \"ERC20Basic: approve owner the zero address\");\r\n        require(spender != address(0), \"ERC20Basic: approve spender the zero address\");\r\n\r\n        _allowances[owner][spender] = amount;\r\n\r\n        emit Approval(owner, spender, amount);\r\n    }\r\n\r\n    /**\r\n     * NOTE: Does not update the allowance if the current allowance\r\n     * is the maximum `uint256`.\r\n     */\r\n    function _spendAllowance(address owner, address spender, uint256 amount) internal {\r\n        uint256 currentAllowance = allowance(owner, spender);\r\n        require(currentAllowance \u003e= amount, \"ERC20Basic: insufficient allowance\");\r\n\r\n        if (currentAllowance != type(uint256).max) {\r\n            unchecked {\r\n                _approve(owner, spender, currentAllowance - amount);\r\n            }\r\n        }\r\n    }\r\n\r\n    function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\r\n        uint256 currentAllowance = allowance(msg.sender, spender);\r\n        unchecked {\r\n            uint256 newAllowance = currentAllowance + addedValue;\r\n            require(newAllowance \u003e= currentAllowance, \"ERC20Basic: overflow of the allowance\");\r\n\r\n            _approve(msg.sender, spender, newAllowance);\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\r\n        uint256 currentAllowance = allowance(msg.sender, spender);\r\n        require(currentAllowance \u003e= subtractedValue, \"ERC20Basic: decreased allowance below zero\");\r\n\r\n        unchecked {\r\n            _approve(msg.sender, spender, currentAllowance - subtractedValue);\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    function lock(address account, uint256 amount) public onlyWhitelisted returns (bool) {\r\n        require(balanceOf(account) \u003e= amount, \"ERC20Basic: Insufficient balance to lock\");\r\n\r\n        unchecked {\r\n            _lockedAmount[account] += amount;\r\n            require(_lockedAmount[account] \u003e= amount, \"ERC20Basic: overflow of locked amount\");\r\n\r\n            emit Lock(msg.sender, account, amount);\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    function unlock(address account, uint256 amount) public onlyWhitelisted returns (bool) {\r\n        require(_lockedAmount[account] \u003e= amount, \"ERC20Basic: underflow of locked amount\");\r\n\r\n        unchecked {\r\n            _lockedAmount[account] -= amount;\r\n\r\n            emit Unlock(msg.sender, account, amount);\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    function transferWithLock(address to, uint256 amount) public onlyWhitelisted returns (bool) {\r\n        _transfer(msg.sender, to, amount);\r\n        lock(to, amount);\r\n\r\n        return true;\r\n    }\r\n}"},"IERC20.sol":{"content":"// SPDX-License-Identifier: MIT\r\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\r\n\r\npragma solidity ^0.8.9;\r\n\r\n/**\r\n * @dev Interface of the ERC20 standard as defined in the EIP.\r\n */\r\ninterface IERC20 {\r\n    // OPTIONAL public state variable getter is automatically generated.\r\n    // function name() public view returns (string);\r\n    // function symbol() public view returns (uint8);\r\n    // function decimals() public view returns (uint256);\r\n\r\n    /**\r\n     * @return The amount of tokens in existence.\r\n     */\r\n    function totalSupply() external view returns (uint256);\r\n\r\n    /**\r\n     * @param account ? caller msg.sender ?\r\n     * @return The amount of tokens owned by `account`.\r\n     */\r\n    function balanceOf(address account) external view returns (uint256);\r\n\r\n    /**\r\n     * @dev This is zero by default.\r\n     * This value changes when {approve} or {transferFrom} are called.\r\n     *\r\n     * @return The remaining number of tokens that `spender` will be\r\n     * allowed to spend on behalf of `owner` through {transferFrom}.\r\n     */\r\n    function allowance(address owner, address spender) external view returns (uint256);\r\n\r\n    /**\r\n     * @dev Moves `amount` tokens from the caller\u0027s account to `to`.\r\n     *\r\n     * Emits a {Transfer} event.\r\n     *\r\n     * @return A boolean value indicating whether the operation succeeded.\r\n     */\r\n    function transfer(address to, uint256 amount) external returns (bool);\r\n\r\n    /**\r\n     * @dev Sets `amount` as the allowance of `spender` over the caller\u0027s tokens.\r\n     *\r\n     * Emits an {Approval} event.\r\n     *\r\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\r\n     * that someone may use both the old and the new allowance by unfortunate\r\n     * transaction ordering. One possible solution to mitigate this race\r\n     * condition is to first reduce the spender\u0027s allowance to 0 and set the\r\n     * desired value afterwards:\r\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\r\n     *\r\n     * @return A boolean value indicating whether the operation succeeded.\r\n     */\r\n    function approve(address spender, uint256 amount) external returns (bool);\r\n\r\n    /**\r\n     * @dev Moves `amount` tokens from `from` to `to` using the\r\n     * allowance mechanism. `amount` is then deducted from the caller\u0027s\r\n     * allowance.\r\n     *\r\n     * Emits a {Transfer} event.\r\n     *\r\n     * @return A boolean value indicating whether the operation succeeded.\r\n     */\r\n    function transferFrom(\r\n        address from,\r\n        address to,\r\n        uint256 amount\r\n    ) external returns (bool);\r\n\r\n    /**\r\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\r\n     * another (`to`).\r\n     *\r\n     * Note that `value` may be zero.\r\n     */\r\n    event Transfer(address indexed from, address indexed to, uint256 value);\r\n\r\n    /**\r\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\r\n     * a call to {approve}.\r\n     * `value` is the new allowance.\r\n     */\r\n    event Approval(address indexed owner, address indexed spender, uint256 value);\r\n}"},"Ownable.sol":{"content":"// SPDX-License-Identifier: MIT\r\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\r\n\r\npragma solidity ^0.8.9;\r\n\r\n/**\r\n * @dev Contract module which provides a basic access control mechanism, where\r\n * there is an account (an owner) that can be granted exclusive access to\r\n * specific functions.\r\n *\r\n * By default, the owner account will be the one that deploys the contract. This\r\n * can later be changed with {transferOwnership}.\r\n *\r\n * This module is used through inheritance. It will make available the modifier\r\n * `onlyOwner`, which can be applied to your functions to restrict their use to\r\n * the owner.\r\n */\r\nabstract contract Ownable {\r\n    address private _owner;\r\n\r\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\r\n\r\n    /**\r\n     * @dev Initializes the contract setting the deployer as the initial owner.\r\n     */\r\n    constructor() {\r\n        _transferOwnership(msg.sender);\r\n    }\r\n\r\n    /**\r\n     * @dev Returns the address of the current owner.\r\n     */\r\n    function owner() public view virtual returns (address) {\r\n        return _owner;\r\n    }\r\n\r\n    /**\r\n     * @dev Throws if called by any account other than the owner.\r\n     */\r\n    modifier onlyOwner() {\r\n        require(owner() == msg.sender, \"Ownable: caller is not the owner\");\r\n        _;\r\n    }\r\n\r\n    /**\r\n     * @dev Leaves the contract without owner. It will not be possible to call\r\n     * `onlyOwner` functions anymore. Can only be called by the current owner.\r\n     *\r\n     * NOTE: Renouncing ownership will leave the contract without an owner,\r\n     * thereby removing any functionality that is only available to the owner.\r\n     */\r\n    function renounceOwnership() public virtual onlyOwner {\r\n        _transferOwnership(address(0));\r\n    }\r\n\r\n    /**\r\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\r\n     * Can only be called by the current owner.\r\n     */\r\n    function transferOwnership(address newOwner) public virtual onlyOwner {\r\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\r\n        _transferOwnership(newOwner);\r\n    }\r\n\r\n    /**\r\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\r\n     * Internal function without access restriction.\r\n     */\r\n    function _transferOwnership(address newOwner) internal virtual {\r\n        address oldOwner = _owner;\r\n        _owner = newOwner;\r\n        emit OwnershipTransferred(oldOwner, newOwner);\r\n    }\r\n}"},"Whitelist.sol":{"content":"// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.8.9;\r\n\r\nimport \"./Ownable.sol\";\r\n\r\ncontract Whitelist is Ownable {\r\n    mapping(address =\u003e bool) private whitelist;\r\n    mapping(address =\u003e uint) private addressIdx;\r\n    address[] private whiteArr;\r\n\r\n    event WhitelistedAddressAdded(address addr);\r\n    event WhitelistedAddressRemoved(address addr);\r\n\r\n    constructor() {\r\n        addAddressToWhitelist(msg.sender);\r\n    }\r\n\r\n    modifier onlyWhitelisted() {\r\n        require(whitelist[msg.sender]);\r\n        _;\r\n    }\r\n\r\n    function isWhitelist(address addr) public view returns (bool success) {\r\n        return whitelist[addr];\r\n    }\r\n\r\n    function addAddressToWhitelist(address addr) onlyOwner public returns (bool success) {\r\n        if (!whitelist[addr]) {\r\n            whitelist[addr] = true;\r\n            addressIdx[addr] = whiteArr.length;\r\n            whiteArr.push(addr);\r\n\r\n            emit WhitelistedAddressAdded(addr);\r\n            success = true;\r\n        }\r\n    }\r\n\r\n    function removeAddressFromWhitelist(address addr) onlyOwner public returns (bool success) {\r\n        if (whitelist[addr]) {\r\n            whitelist[addr] = false;\r\n            uint deleteIdx = addressIdx[addr];\r\n            address lastAddr = whiteArr[whiteArr.length - 1];\r\n            addressIdx[lastAddr] = deleteIdx;\r\n            delete addressIdx[addr];\r\n            whiteArr[deleteIdx] = lastAddr;\r\n            whiteArr.pop();\r\n\r\n            emit WhitelistedAddressRemoved(addr);\r\n            success = true;\r\n        }\r\n    }\r\n\r\n    function getCountWhiteArr() public onlyOwner view returns (uint count) {\r\n        count = whiteArr.length;\r\n    }\r\n\r\n    function getWhiteArrByIdx(uint idx) public onlyOwner view returns (address whiteAddress) {\r\n        whiteAddress = whiteArr[idx];\r\n    }\r\n\r\n    function getWhiteArr() public onlyOwner view returns (address[] memory whiteArray) {\r\n        whiteArray = whiteArr;\r\n    }\r\n}"}}