Transaction Hash:
Block:
20877721 at Oct-02-2024 12:09:11 PM +UTC
Transaction Fee:
0.0003651935977186 ETH
$0.89
Gas Used:
46,340 Gas / 7.88074229 Gwei
Emitted Events:
523 |
SideToken.Approval( owner=[Sender] 0x0c8afa31d68028ed8054493ee92f52b82ab992a2, spender=0x33C0D33a...C47366EE1, value=9338000000000000000000 )
|
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x0C8aFa31...82AB992A2 |
0.849350960582326772 Eth
Nonce: 9329
|
0.848985766984608172 Eth
Nonce: 9330
| 0.0003651935977186 | ||
0x4838B106...B0BAD5f97
Miner
| (Titan Builder) | 5.274080868201560291 Eth | 5.274080872950854211 Eth | 0.00000000474929392 | |
0xbdab7260...113B8F7a5 |
Execution Trace
SideToken.approve( spender=0x33C0D33a0d4312562ad622F91d12B0AC47366EE1, value=9338000000000000000000 ) => ( True )
{"Address.sol":{"content":"pragma solidity ^0.5.0;\n\n/**\n * @dev Collection of functions related to the address type,\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\n // for accounts without code, i.e. `keccak256(\u0027\u0027)`\n bytes32 codehash;\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\n // solhint-disable-next-line no-inline-assembly\n assembly { codehash := extcodehash(account) }\n return (codehash != accountHash \u0026\u0026 codehash != 0x0);\n }\n}\n"},"Context.sol":{"content":"pragma solidity ^0.5.0;\n\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with GSN meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\ncontract Context {\n // Empty internal constructor, to prevent people from mistakenly deploying\n // an instance of this contract, which should be used via inheritance.\n constructor () internal { }\n // solhint-disable-previous-line no-empty-blocks\n\n function _msgSender() internal view returns (address payable) {\n return msg.sender;\n }\n\n function _msgData() internal view returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n"},"ERC777.sol":{"content":"pragma solidity ^0.5.0;\n\nimport \"./Context.sol\";\nimport \"./IERC777.sol\";\nimport \"./IERC777Recipient.sol\";\nimport \"./IERC777Sender.sol\";\nimport \"./IERC20.sol\";\nimport \"./SafeMath.sol\";\nimport \"./Address.sol\";\nimport \"./IERC1820Registry.sol\";\n\n/**\n * @dev Implementation of the {IERC777} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * Support for ERC20 is included in this contract, as specified by the EIP: both\n * the ERC777 and ERC20 interfaces can be safely used when interacting with it.\n * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token\n * movements.\n *\n * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there\n * are no special restrictions in the amount of tokens that created, moved, or\n * destroyed. This makes integration with ERC20 applications seamless.\n */\ncontract ERC777 is Context, IERC777, IERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n IERC1820Registry constant private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);\n\n mapping(address =\u003e uint256) private _balances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n // We inline the result of the following hashes because Solidity doesn\u0027t resolve them at compile time.\n // See https://github.com/ethereum/solidity/issues/4024.\n\n // keccak256(\"ERC777TokensSender\")\n bytes32 constant private TOKENS_SENDER_INTERFACE_HASH =\n 0x29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe895;\n\n // keccak256(\"ERC777TokensRecipient\")\n bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH =\n 0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b;\n\n // This isn\u0027t ever read from - it\u0027s only used to respond to the defaultOperators query.\n address[] private _defaultOperatorsArray;\n\n // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).\n mapping(address =\u003e bool) private _defaultOperators;\n\n // For each account, a mapping of its operators and revoked default operators.\n mapping(address =\u003e mapping(address =\u003e bool)) private _operators;\n mapping(address =\u003e mapping(address =\u003e bool)) private _revokedDefaultOperators;\n\n // ERC20-allowances\n mapping (address =\u003e mapping (address =\u003e uint256)) private _allowances;\n\n /**\n * @dev `defaultOperators` may be an empty array.\n */\n constructor(\n string memory name,\n string memory symbol,\n address[] memory defaultOperators\n ) public {\n _name = name;\n _symbol = symbol;\n\n _defaultOperatorsArray = defaultOperators;\n for (uint256 i = 0; i \u003c _defaultOperatorsArray.length; i++) {\n _defaultOperators[_defaultOperatorsArray[i]] = true;\n }\n\n // register interfaces\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC777Token\"), address(this));\n _erc1820.setInterfaceImplementer(address(this), keccak256(\"ERC20Token\"), address(this));\n }\n\n /**\n * @dev See {IERC777-name}.\n */\n function name() public view returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC777-symbol}.\n */\n function symbol() public view returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {ERC20Detailed-decimals}.\n *\n * Always returns 18, as per the\n * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).\n */\n function decimals() public pure returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC777-granularity}.\n *\n * This implementation always returns `1`.\n */\n function granularity() public view returns (uint256) {\n return 1;\n }\n\n /**\n * @dev See {IERC777-totalSupply}.\n */\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Returns the amount of tokens owned by an account (`tokenHolder`).\n */\n function balanceOf(address tokenHolder) public view returns (uint256) {\n return _balances[tokenHolder];\n }\n\n /**\n * @dev See {IERC777-send}.\n *\n * Also emits a {Transfer} event for ERC20 compatibility.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external {\n _send(_msgSender(), _msgSender(), recipient, amount, data, \"\", true);\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}\n * interface if it is a contract.\n *\n * Also emits a {Sent} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool) {\n require(recipient != address(0), \"ERC777: transfer to zero address\");\n\n address from = _msgSender();\n\n _callTokensToSend(from, from, recipient, amount, \"\", \"\");\n\n _move(from, from, recipient, amount, \"\", \"\");\n\n _callTokensReceived(from, from, recipient, amount, \"\", \"\", false);\n\n return true;\n }\n\n /**\n * @dev See {IERC777-burn}.\n *\n * Also emits a {Transfer} event for ERC20 compatibility.\n */\n function burn(uint256 amount, bytes calldata data) external {\n _burn(_msgSender(), _msgSender(), amount, data, \"\");\n }\n\n /**\n * @dev See {IERC777-isOperatorFor}.\n */\n function isOperatorFor(\n address operator,\n address tokenHolder\n ) public view returns (bool) {\n return operator == tokenHolder ||\n (_defaultOperators[operator] \u0026\u0026 !_revokedDefaultOperators[tokenHolder][operator]) ||\n _operators[tokenHolder][operator];\n }\n\n /**\n * @dev See {IERC777-authorizeOperator}.\n */\n function authorizeOperator(address operator) external {\n require(_msgSender() != operator, \"ERC777: authorizing self as operator\");\n\n if (_defaultOperators[operator]) {\n delete _revokedDefaultOperators[_msgSender()][operator];\n } else {\n _operators[_msgSender()][operator] = true;\n }\n\n emit AuthorizedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-revokeOperator}.\n */\n function revokeOperator(address operator) external {\n require(operator != _msgSender(), \"ERC777: revoking self as operator\");\n\n if (_defaultOperators[operator]) {\n _revokedDefaultOperators[_msgSender()][operator] = true;\n } else {\n delete _operators[_msgSender()][operator];\n }\n\n emit RevokedOperator(operator, _msgSender());\n }\n\n /**\n * @dev See {IERC777-defaultOperators}.\n */\n function defaultOperators() public view returns (address[] memory) {\n return _defaultOperatorsArray;\n }\n\n /**\n * @dev See {IERC777-operatorSend}.\n *\n * Emits {Sent} and {Transfer} events.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n )\n external\n {\n require(isOperatorFor(_msgSender(), sender), \"ERC777: caller is not an operator\");\n _send(_msgSender(), sender, recipient, amount, data, operatorData, true);\n }\n\n /**\n * @dev See {IERC777-operatorBurn}.\n *\n * Emits {Burned} and {Transfer} events.\n */\n function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData) external {\n require(isOperatorFor(_msgSender(), account), \"ERC777: caller is not an operator\");\n _burn(_msgSender(), account, amount, data, operatorData);\n }\n\n /**\n * @dev See {IERC20-allowance}.\n *\n * Note that operator and allowance concepts are orthogonal: operators may\n * not have allowance, and accounts with allowance may not be operators\n * themselves.\n */\n function allowance(address holder, address spender) public view returns (uint256) {\n return _allowances[holder][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Note that accounts cannot have allowance issued by their operators.\n */\n function approve(address spender, uint256 value) external returns (bool) {\n address holder = _msgSender();\n _approve(holder, spender, value);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Note that operator and allowance concepts are orthogonal: operators cannot\n * call `transferFrom` (unless they have allowance), and accounts with\n * allowance cannot call `operatorSend` (unless they are operators).\n *\n * Emits {Sent}, {Transfer} and {Approval} events.\n */\n function transferFrom(address holder, address recipient, uint256 amount) external returns (bool) {\n require(recipient != address(0), \"ERC777: transfer to zero address\");\n require(holder != address(0), \"ERC777: transfer from zero address\");\n\n address spender = _msgSender();\n\n _callTokensToSend(spender, holder, recipient, amount, \"\", \"\");\n\n _move(spender, holder, recipient, amount, \"\", \"\");\n _approve(holder, spender, _allowances[holder][spender].sub(amount, \"ERC777: transfer amount exceeds allowance\"));\n\n _callTokensReceived(spender, holder, recipient, amount, \"\", \"\", false);\n\n return true;\n }\n\n /**\n * @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `operator`, `data` and `operatorData`.\n *\n * See {IERC777Sender} and {IERC777Recipient}.\n *\n * Emits {Minted} and {Transfer} events.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - if `account` is a contract, it must implement the {IERC777Recipient}\n * interface.\n */\n function _mint(\n address operator,\n address account,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n require(account != address(0), \"ERC777: mint to zero address\");\n\n // Update state variables\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n\n _callTokensReceived(operator, address(0), account, amount, userData, operatorData, true);\n\n emit Minted(operator, account, amount, userData, operatorData);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Send tokens\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _send(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n )\n internal\n {\n require(from != address(0), \"ERC777: send from zero address\");\n require(to != address(0), \"ERC777: send to zero address\");\n\n _callTokensToSend(operator, from, to, amount, userData, operatorData);\n\n _move(operator, from, to, amount, userData, operatorData);\n\n _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);\n }\n\n /**\n * @dev Burn tokens\n * @param operator address operator requesting the operation\n * @param from address token holder address\n * @param amount uint256 amount of tokens to burn\n * @param data bytes extra information provided by the token holder\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _burn(\n address operator,\n address from,\n uint256 amount,\n bytes memory data,\n bytes memory operatorData\n )\n internal\n {\n require(from != address(0), \"ERC777: burn from zero address\");\n\n _callTokensToSend(operator, from, address(0), amount, data, operatorData);\n\n // Update state variables\n _balances[from] = _balances[from].sub(amount, \"ERC777: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n\n emit Burned(operator, from, amount, data, operatorData);\n emit Transfer(from, address(0), amount);\n }\n\n function _move(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n _balances[from] = _balances[from].sub(amount, \"ERC777: transfer amount exceeds balance\");\n _balances[to] = _balances[to].add(amount);\n\n emit Sent(operator, from, to, amount, userData, operatorData);\n emit Transfer(from, to, amount);\n }\n\n function _approve(address holder, address spender, uint256 value) internal {\n // TODO: restore this require statement if this function becomes internal, or is called at a new callsite. It is\n // currently unnecessary.\n //require(holder != address(0), \"ERC777: approve from the zero address\");\n require(spender != address(0), \"ERC777: approve to zero address\");\n\n _allowances[holder][spender] = value;\n emit Approval(holder, spender, value);\n }\n\n /**\n * @dev Call from.tokensToSend() if the interface is registered\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n */\n function _callTokensToSend(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData\n )\n internal\n {\n address implementer = _erc1820.getInterfaceImplementer(from, TOKENS_SENDER_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);\n }\n }\n\n /**\n * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but\n * tokensReceived() was not registered for the recipient\n * @param operator address operator requesting the transfer\n * @param from address token holder address\n * @param to address recipient address\n * @param amount uint256 amount of tokens to transfer\n * @param userData bytes extra information provided by the token holder (if any)\n * @param operatorData bytes extra information provided by the operator (if any)\n * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient\n */\n function _callTokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes memory userData,\n bytes memory operatorData,\n bool requireReceptionAck\n )\n private\n {\n address implementer = _erc1820.getInterfaceImplementer(to, TOKENS_RECIPIENT_INTERFACE_HASH);\n if (implementer != address(0)) {\n IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);\n } else if (requireReceptionAck) {\n require(!to.isContract(), \"ERC777: token recipient contract has no implementer for ERC777TokensRecipient\");\n }\n }\n}\n"},"IERC1820Registry.sol":{"content":"pragma solidity ^0.5.0;\n\n/**\n * @dev Interface of the global ERC1820 Registry, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register\n * implementers for interfaces in this registry, as well as query support.\n *\n * Implementers may be shared by multiple accounts, and can also implement more\n * than a single interface for each account. Contracts can implement interfaces\n * for themselves, but externally-owned accounts (EOA) must delegate this to a\n * contract.\n *\n * {IERC165} interfaces can also be queried via the registry.\n *\n * For an in-depth explanation and source code analysis, see the EIP text.\n */\ninterface IERC1820Registry {\n /**\n * @dev Sets `newManager` as the manager for `account`. A manager of an\n * account is able to set interface implementers for it.\n *\n * By default, each account is its own manager. Passing a value of `0x0` in\n * `newManager` will reset the manager to this initial state.\n *\n * Emits a {ManagerChanged} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n */\n function setManager(address account, address newManager) external;\n\n /**\n * @dev Returns the manager for `account`.\n *\n * See {setManager}.\n */\n function getManager(address account) external view returns (address);\n\n /**\n * @dev Sets the `implementer` contract as `account`\u0027s implementer for\n * `interfaceHash`.\n *\n * `account` being the zero address is an alias for the caller\u0027s address.\n * The zero address can also be used in `implementer` to remove an old one.\n *\n * See {interfaceHash} to learn how these are created.\n *\n * Emits an {InterfaceImplementerSet} event.\n *\n * Requirements:\n *\n * - the caller must be the current manager for `account`.\n * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not\n * end in 28 zeroes).\n * - `implementer` must implement {IERC1820Implementer} and return true when\n * queried for support, unless `implementer` is the caller. See\n * {IERC1820Implementer-canImplementInterfaceForAddress}.\n */\n function setInterfaceImplementer(address account, bytes32 interfaceHash, address implementer) external;\n\n /**\n * @dev Returns the implementer of `interfaceHash` for `account`. If no such\n * implementer is registered, returns the zero address.\n *\n * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28\n * zeroes), `account` will be queried for support of it.\n *\n * `account` being the zero address is an alias for the caller\u0027s address.\n */\n function getInterfaceImplementer(address account, bytes32 interfaceHash) external view returns (address);\n\n /**\n * @dev Returns the interface hash for an `interfaceName`, as defined in the\n * corresponding\n * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].\n */\n function interfaceHash(string calldata interfaceName) external pure returns (bytes32);\n\n /**\n * @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n * @param account Address of the contract for which to update the cache.\n * @param interfaceId ERC165 interface for which to update the cache.\n */\n function updateERC165Cache(address account, bytes4 interfaceId) external;\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not.\n * If the result is not cached a direct lookup on the contract address is performed.\n * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n * {updateERC165Cache} with the contract address.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);\n\n /**\n * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.\n * @param account Address of the contract to check.\n * @param interfaceId ERC165 interface to check.\n * @return True if `account` implements `interfaceId`, false otherwise.\n */\n function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);\n\n event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);\n\n event ManagerChanged(address indexed account, address indexed newManager);\n}\n"},"IERC20.sol":{"content":"pragma solidity ^0.5.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP. Does not include\n * the optional functions; to access them see {ERC20Detailed}.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller\u0027s account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller\u0027s tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender\u0027s allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller\u0027s\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"},"IERC677Receiver.sol":{"content":"pragma solidity ^0.5.0;\n\ninterface IERC677Receiver {\n function onTokenTransfer(address _sender, uint _value, bytes calldata _data) external;\n}"},"IERC777.sol":{"content":"pragma solidity ^0.5.0;\n\n/**\n * @dev Interface of the ERC777Token standard as defined in the EIP.\n *\n * This contract uses the\n * [ERC1820 registry standard](https://eips.ethereum.org/EIPS/eip-1820) to let\n * token holders and recipients react to token movements by using setting implementers\n * for the associated interfaces in said registry. See `IERC1820Registry` and\n * `ERC1820Implementer`.\n */\ninterface IERC777 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the smallest part of the token that is not divisible. This\n * means all token operations (creation, movement and destruction) must have\n * amounts that are a multiple of this number.\n *\n * For most token contracts, this value will equal 1.\n */\n function granularity() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by an account (`owner`).\n */\n function balanceOf(address owner) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller\u0027s account to `recipient`.\n *\n * If send or receive hooks are registered for the caller and `recipient`,\n * the corresponding functions will be called with `data` and empty\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\n *\n * Emits a `Sent` event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the `tokensReceived`\n * interface.\n */\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Destroys `amount` tokens from the caller\u0027s account, reducing the\n * total supply.\n *\n * If a send hook is registered for the caller, the corresponding function\n * will be called with `data` and empty `operatorData`. See `IERC777Sender`.\n *\n * Emits a `Burned` event.\n *\n * Requirements\n *\n * - the caller must have at least `amount` tokens.\n */\n function burn(uint256 amount, bytes calldata data) external;\n\n /**\n * @dev Returns true if an account is an operator of `tokenHolder`.\n * Operators can send and burn tokens on behalf of their owners. All\n * accounts are their own operator.\n *\n * See `operatorSend` and `operatorBurn`.\n */\n function isOperatorFor(address operator, address tokenHolder) external view returns (bool);\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See `isOperatorFor`.\n *\n * Emits an `AuthorizedOperator` event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function authorizeOperator(address operator) external;\n\n /**\n * @dev Make an account an operator of the caller.\n *\n * See `isOperatorFor` and `defaultOperators`.\n *\n * Emits a `RevokedOperator` event.\n *\n * Requirements\n *\n * - `operator` cannot be calling address.\n */\n function revokeOperator(address operator) external;\n\n /**\n * @dev Returns the list of default operators. These accounts are operators\n * for all token holders, even if `authorizeOperator` was never called on\n * them.\n *\n * This list is immutable, but individual holders may revoke these via\n * `revokeOperator`, in which case `isOperatorFor` will return false.\n */\n function defaultOperators() external view returns (address[] memory);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must\n * be an operator of `sender`.\n *\n * If send or receive hooks are registered for `sender` and `recipient`,\n * the corresponding functions will be called with `data` and\n * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.\n *\n * Emits a `Sent` event.\n *\n * Requirements\n *\n * - `sender` cannot be the zero address.\n * - `sender` must have at least `amount` tokens.\n * - the caller must be an operator for `sender`.\n * - `recipient` cannot be the zero address.\n * - if `recipient` is a contract, it must implement the `tokensReceived`\n * interface.\n */\n function operatorSend(\n address sender,\n address recipient,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n /**\n * @dev Destoys `amount` tokens from `account`, reducing the total supply.\n * The caller must be an operator of `account`.\n *\n * If a send hook is registered for `account`, the corresponding function\n * will be called with `data` and `operatorData`. See `IERC777Sender`.\n *\n * Emits a `Burned` event.\n *\n * Requirements\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n * - the caller must be an operator for `account`.\n */\n function operatorBurn(\n address account,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n\n event Sent(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256 amount,\n bytes data,\n bytes operatorData\n );\n\n event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);\n\n event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);\n\n event AuthorizedOperator(address indexed operator, address indexed tokenHolder);\n\n event RevokedOperator(address indexed operator, address indexed tokenHolder);\n}\n"},"IERC777Recipient.sol":{"content":"pragma solidity ^0.5.0;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of `IERC777` tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\n *\n * See `IERC1820Registry` and `ERC1820Implementer`.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an `IERC777` token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract\u0027s state is updated, so\n * `IERC777.balanceOf`, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n"},"IERC777Sender.sol":{"content":"pragma solidity ^0.5.0;\n\n/**\n * @dev Interface of the ERC777TokensSender standard as defined in the EIP.\n *\n * `IERC777` Token holders can be notified of operations performed on their\n * tokens by having a contract implement this interface (contract holders can be\n * their own implementer) and registering it on the\n * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).\n *\n * See `IERC1820Registry` and `ERC1820Implementer`.\n */\ninterface IERC777Sender {\n /**\n * @dev Called by an `IERC777` token contract whenever a registered holder\u0027s\n * (`from`) tokens are about to be moved or destroyed. The type of operation\n * is conveyed by `to` being the zero address or not.\n *\n * This call occurs _before_ the token contract\u0027s state is updated, so\n * `IERC777.balanceOf`, etc., can be used to query the pre-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensToSend(\n address operator,\n address from,\n address to,\n uint amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n"},"ISideToken.sol":{"content":"pragma solidity ^0.5.0;\n\ninterface ISideToken {\n\n function name() external view returns (string memory);\n\n function symbol() external view returns (string memory);\n\n function decimals() external pure returns (uint8);\n\n function granularity() external view returns (uint256);\n\n function burn(uint256 amount, bytes calldata data) external;\n\n function mint(address account, uint256 amount, bytes calldata userData, bytes calldata operatorData) external;\n\n function totalSupply() external view returns (uint256);\n\n function balanceOf(address owner) external view returns (uint256);\n\n function send(address recipient, uint256 amount, bytes calldata data) external;\n\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n function allowance(address owner, address spender) external view returns (uint256);\n\n function approve(address spender, uint256 amount) external returns (bool);\n\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n}"},"SafeMath.sol":{"content":"pragma solidity ^0.5.0;\n\n/**\n * @dev Wrappers over Solidity\u0027s arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it\u0027s recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity\u0027s `+` operator.\n *\n * Requirements:\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c \u003e= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity\u0027s `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity\u0027s `-` operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n *\n * _Available since v2.4.0._\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b \u003c= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity\u0027s `*` operator.\n *\n * Requirements:\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring \u0027a\u0027 not being zero, but the\n // benefit is lost if \u0027b\u0027 is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity\u0027s `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity\u0027s `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n *\n * _Available since v2.4.0._\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n // Solidity only automatically asserts when dividing by 0\n require(b \u003e 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn\u0027t hold\n\n return c;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts when dividing by zero.\n *\n * Counterpart to Solidity\u0027s `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts with custom message when dividing by zero.\n *\n * Counterpart to Solidity\u0027s `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n * - The divisor cannot be zero.\n *\n * _Available since v2.4.0._\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n}\n"},"SideToken.sol":{"content":"pragma solidity ^0.5.0;\n\nimport \"./ERC777.sol\";\nimport \"./IERC677Receiver.sol\";\nimport \"./ISideToken.sol\";\n\ncontract SideToken is ISideToken, ERC777 {\n using Address for address;\n using SafeMath for uint256;\n\n address public minter;\n uint256 private _granularity;\n\n event Transfer(address,address,uint256,bytes);\n\n constructor(string memory _tokenName, string memory _tokenSymbol, address _minterAddr, uint256 _newGranularity)\n ERC777(_tokenName, _tokenSymbol, new address[](0)) public {\n require(_minterAddr != address(0), \"SideToken: Minter address is null\");\n require(_newGranularity \u003e= 1, \"SideToken: Granularity must be equal or bigger than 1\");\n minter = _minterAddr;\n _granularity = _newGranularity;\n }\n\n modifier onlyMinter() {\n require(_msgSender() == minter, \"SideToken: Caller is not the minter\");\n _;\n }\n\n function mint(\n address account,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n )\n external onlyMinter\n {\n _mint(_msgSender(), account, amount, userData, operatorData);\n }\n\n /**\n * @dev ERC677 transfer token with additional data if the recipient is a contact.\n * @param recipient The address to transfer to.\n * @param amount The amount to be transferred.\n * @param data The extra data to be passed to the receiving contract.\n */\n function transferAndCall(address recipient, uint amount, bytes calldata data)\n external returns (bool success)\n {\n address from = _msgSender();\n\n _send(from, from, recipient, amount, data, \"\", false);\n emit Transfer(from, recipient, amount, data);\n IERC677Receiver(recipient).onTokenTransfer(from, amount, data);\n return true;\n }\n\n function granularity() public view returns (uint256) {\n return _granularity;\n }\n\n}"}}