ETH Price: $2,440.32 (+3.90%)

Transaction Decoder

Block:
19716943 at Apr-23-2024 08:36:35 AM +UTC
Transaction Fee:
0.000553495975163851 ETH $1.35
Gas Used:
46,457 Gas / 11.914156643 Gwei

Emitted Events:

183 CredefiToken.Approval( owner=[Sender] 0xed5ccd9bde541a29ca9e1d10a449fe96c24f1b03, spender=0x00000000...43aC78BA3, value=115792089237316195423570985008687907853269984665640564039457584007913129639935 )

Account State Difference:

  Address   Before After State Difference Code
(Titan Builder)
8.288533126243404529 Eth8.288628152074932505 Eth0.000095025831527976
0xaE6e307c...49c014c6B
0xEd5CCd9B...6C24F1b03
0.01163 Eth
Nonce: 0
0.011076504024836149 Eth
Nonce: 1
0.000553495975163851

Execution Trace

CredefiToken.approve( spender=0x000000000022D473030F116dDEE9F6B43aC78BA3, value=115792089237316195423570985008687907853269984665640564039457584007913129639935 ) => ( True )
{"CredefiToken.sol":{"content":"// SPDX-License-Identifier:MIT\npragma solidity 0.8.10;\n\nimport \"./IERC20.sol\";\n\ncontract CredefiToken is IERC20 {\n    // bytes32 private constant EIP712DOMAIN_HASH =\n    // keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\")\n    bytes32 private constant EIP712DOMAIN_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\n\n    // bytes32 private constant NAME_HASH = keccak256(\"Credi\")\n    bytes32 private constant NAME_HASH = 0x3c5eac0879bc46be0fe2a2701e57d8e6edcaa427c79074f4513eb9572ff50507;\n\n    // bytes32 private constant VERSION_HASH = keccak256(\"1\")\n    bytes32 private constant VERSION_HASH = 0xc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6;\n\n    // bytes32 public constant PERMIT_TYPEHASH =\n    // keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n    bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;\n\n    // bytes32 public constant TRANSFER_WITH_AUTHORIZATION_TYPEHASH =\n    // keccak256(\"TransferWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)\");\n    bytes32 public constant TRANSFER_WITH_AUTHORIZATION_TYPEHASH =\n        0x7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a2267;\n\n    string public constant name = \"CREDI\";\n    string public constant symbol = \"CREDI\";\n    uint8 public constant decimals = 18;\n\n    address public timelock;\n    uint256 public override totalSupply;\n\n    mapping(address =\u003e uint256) public override balanceOf;\n    mapping(address =\u003e mapping(address =\u003e uint256)) public override allowance;\n\n    // ERC-2612, ERC-3009 state\n    mapping(address =\u003e uint256) public nonces;\n    mapping(address =\u003e mapping(bytes32 =\u003e bool)) public authorizationState;\n\n    event AuthorizationUsed(address indexed authorizer, bytes32 indexed nonce);\n    event TimelockUpdated(address indexed timelock);\n\n    modifier onlyTimelock() {\n        require(msg.sender == address(timelock), \"CREDI:NOT_TIMELOCK\");\n        _;\n    }\n\n    constructor(address _timelock) {\n        _changeTimelock(_timelock);\n    }\n\n    function changeTimelock(address _timelock) external onlyTimelock {\n        _changeTimelock(_timelock);\n    }\n\n    function mint(address to, uint256 value) external onlyTimelock returns (bool) {\n        _mint(to, value);\n        return true;\n    }\n\n    function burn(uint256 value) external returns (bool) {\n        _burn(msg.sender, value);\n        return true;\n    }\n\n    function approve(address spender, uint256 value) external override returns (bool) {\n        _approve(msg.sender, spender, value);\n        return true;\n    }\n\n    function transfer(address to, uint256 value) external override returns (bool) {\n        _transfer(msg.sender, to, value);\n        return true;\n    }\n\n    function transferFrom(\n        address from,\n        address to,\n        uint256 value\n    ) external override returns (bool) {\n        uint256 fromAllowance = allowance[from][msg.sender];\n        if (fromAllowance != type(uint256).max) {\n            // Allowance is implicitly checked with Solidity\u0027s underflow protection\n            allowance[from][msg.sender] = fromAllowance - value;\n        }\n        _transfer(from, to, value);\n        return true;\n    }\n\n    function permit(\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external {\n        require(deadline \u003e= block.timestamp, \"CREDI:AUTH_EXPIRED\");\n\n        bytes32 encodeData = keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner], deadline));\n        nonces[owner] = nonces[owner] + 1;\n        _validateSignedData(owner, encodeData, v, r, s);\n\n        _approve(owner, spender, value);\n    }\n\n    function transferWithAuthorization(\n        address from,\n        address to,\n        uint256 value,\n        uint256 validAfter,\n        uint256 validBefore,\n        bytes32 nonce,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external {\n        require(block.timestamp \u003e validAfter, \"CREDI:AUTH_NOT_YET_VALID\");\n        require(block.timestamp \u003c validBefore, \"CREDI:AUTH_EXPIRED\");\n        require(!authorizationState[from][nonce], \"CREDI:AUTH_ALREADY_USED\");\n\n        bytes32 encodeData = keccak256(\n            abi.encode(TRANSFER_WITH_AUTHORIZATION_TYPEHASH, from, to, value, validAfter, validBefore, nonce)\n        );\n        _validateSignedData(from, encodeData, v, r, s);\n\n        authorizationState[from][nonce] = true;\n        emit AuthorizationUsed(from, nonce);\n\n        _transfer(from, to, value);\n    }\n\n    function getChainId() public view returns (uint256 chainId) {\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            chainId := chainid()\n        }\n    }\n\n    function getDomainSeparator() public view returns (bytes32) {\n        return keccak256(abi.encode(EIP712DOMAIN_HASH, NAME_HASH, VERSION_HASH, getChainId(), address(this)));\n    }\n\n    function _changeTimelock(address _timelock) internal {\n        timelock = _timelock;\n        emit TimelockUpdated(_timelock);\n    }\n\n    function _validateSignedData(\n        address signer,\n        bytes32 encodeData,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) internal view {\n        bytes32 digest = keccak256(abi.encodePacked(\"\\x19\\x01\", getDomainSeparator(), encodeData));\n        address recoveredAddress = ecrecover(digest, v, r, s);\n        // Explicitly disallow authorizations for address(0) as ecrecover returns address(0) on malformed messages\n        require(recoveredAddress != address(0) \u0026\u0026 recoveredAddress == signer, \"CREDI:INVALID_SIGNATURE\");\n    }\n\n    function _mint(address to, uint256 value) internal {\n        totalSupply = totalSupply + value;\n        balanceOf[to] = balanceOf[to] + value;\n        emit Transfer(address(0), to, value);\n    }\n\n    function _burn(address from, uint256 value) internal {\n        // Balance is implicitly checked with Solidity\u0027s underflow protection\n        balanceOf[from] = balanceOf[from] - value;\n        totalSupply = totalSupply - value;\n        emit Transfer(from, address(0), value);\n    }\n\n    function _approve(\n        address owner,\n        address spender,\n        uint256 value\n    ) private {\n        allowance[owner][spender] = value;\n        emit Approval(owner, spender, value);\n    }\n\n    function _transfer(\n        address from,\n        address to,\n        uint256 value\n    ) private {\n        require(to != address(this) \u0026\u0026 to != address(0), \"CREDI:RECEIVER_IS_TOKEN_OR_ZERO\");\n\n        // Balance is implicitly checked with Solidity\u0027s underflow protection\n        balanceOf[from] = balanceOf[from] - value;\n        balanceOf[to] = balanceOf[to] + value;\n        emit Transfer(from, to, value);\n    }\n}\n"},"IERC20.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\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(\n        address sender,\n        address recipient,\n        uint256 amount\n    ) 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"}}