Transaction Hash:
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:
| 454 |
ERC20Basic.Transfer( from=[Sender] 0x2fca9628ebca401fa0b6064f47b2a839dd4cc94b, to=0xf78398c0842C29Fc00C76470340b543EE1B2d162, value=6000000000000000000000000 )
|
Account State Difference:
| Address | Before | After | State Difference | ||
|---|---|---|---|---|---|
| 0x2fca9628...9dD4cC94B |
0.026297348050019319 Eth
Nonce: 108
|
0.025237114517588413 Eth
Nonce: 109
| 0.001060233532430906 | ||
|
0x95222290...5CC4BAfe5
Miner
| (beaverbuild) | 13.456957229144784261 Eth | 13.456961430453089852 Eth | 0.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}"}}