Cryo Explorer Ethereum Mainnet

Address Contract Verified

Address 0x7CAB80B6FaCD52A0F3e044D8bfC43d0ad6D258F4
Balance 0 ETH
Nonce 23
Code Size 4279 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

4279 bytes
0x608060405234801561001057600080fd5b50600061001b61008b565b600080356001600160e01b0319168152602082905260409020549091506001600160a01b0316806100675760405162461bcd60e51b815260040161005e90610e21565b60405180910390fd5b3660008037600080366000845af43d6000803e808015610086573d6000f35b3d6000fd5b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c90565b60005b83518110156101ec5760008482815181106100c957fe5b6020026020010151602001519050600060028111156100e457fe5b8160028111156100f057fe5b14156101335761012e85838151811061010557fe5b60200260200101516000015186848151811061011d57fe5b602002602001015160400151610237565b6101e3565b600181600281111561014157fe5b141561017f5761012e85838151811061015657fe5b60200260200101516000015186848151811061016e57fe5b6020026020010151604001516103b7565b600281600281111561018d57fe5b14156101cb5761012e8583815181106101a257fe5b6020026020010151600001518684815181106101ba57fe5b602002602001015160400151610541565b60405162461bcd60e51b815260040161005e90610d8e565b506001016100b2565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67383838360405161022093929190610b42565b60405180910390a161023282826105fc565b505050565b60008151116102585760405162461bcd60e51b815260040161005e90610ce6565b600061026261008b565b90506001600160a01b03831661028a5760405162461bcd60e51b815260040161005e90610dd5565b6001600160a01b038316600090815260018201602052604090205461ffff811661032c576102d08460405180606001604052806024815260200161105e60249139610723565b6002820180546001600160a01b038616600081815260018087016020908152604083208201805461ffff191661ffff90961695909517909455845490810185559381529190912090910180546001600160a01b03191690911790555b60005b83518110156103b057600084828151811061034657fe5b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b031680156103965760405162461bcd60e51b815260040161005e90610f01565b6103a28583868a610744565b50506001918201910161032f565b5050505050565b60008151116103d85760405162461bcd60e51b815260040161005e90610ce6565b60006103e261008b565b90506001600160a01b03831661040a5760405162461bcd60e51b815260040161005e90610dd5565b6001600160a01b038316600090815260018201602052604090205461ffff81166104ac576104508460405180606001604052806024815260200161105e60249139610723565b6002820180546001600160a01b038616600081815260018087016020908152604083208201805461ffff191661ffff90961695909517909455845490810185559381529190912090910180546001600160a01b03191690911790555b60005b83518110156103b05760008482815181106104c657fe5b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b0390811690871681141561051c5760405162461bcd60e51b815260040161005e90610f56565b6105278582846107e7565b6105338583868a610744565b5050600191820191016104af565b60008151116105625760405162461bcd60e51b815260040161005e90610ce6565b600061056c61008b565b90506001600160a01b038316156105955760405162461bcd60e51b815260040161005e90610fb3565b60005b82518110156105f65760008382815181106105af57fe5b6020908102919091018101516001600160e01b031981166000908152918590526040909120549091506001600160a01b03166105ec8482846107e7565b5050600101610598565b50505050565b6001600160a01b03821661062e578051156106295760405162461bcd60e51b815260040161005e90610c43565b61071f565b600081511161064f5760405162461bcd60e51b815260040161005e90610e56565b6001600160a01b0382163014610681576106818260405180606001604052806028815260200161103660289139610723565b600080836001600160a01b03168360405161069c9190610b26565b600060405180830381855af49150503d80600081146106d7576040519150601f19603f3d011682016040523d82523d6000602084013e6106dc565b606091505b5091509150816105f657805115610707578060405162461bcd60e51b815260040161005e9190610c29565b60405162461bcd60e51b815260040161005e90610ca0565b5050565b813b81816105f65760405162461bcd60e51b815260040161005e9190610c29565b6001600160e01b03198316600081815260208681526040808320805461ffff60a01b1916600160a01b61ffff98909816979097029690961786556001600160a01b0394909416808352600180890183529483208054958601815583528183206008860401805463ffffffff60079097166004026101000a968702191660e09890981c9590950296909617909355529290925281546001600160a01b031916179055565b6001600160a01b03821661080d5760405162461bcd60e51b815260040161005e90610d31565b6001600160a01b0382163014156108365760405162461bcd60e51b815260040161005e90610eb3565b6001600160e01b03198116600090815260208481526040808320546001600160a01b03861684526001870190925290912054600160a01b90910461ffff169060001901808214610957576001600160a01b038416600090815260018601602052604081208054839081106108a657fe5b600091825260208083206008830401546001600160a01b038916845260018a019091526040909220805460079092166004026101000a90920460e01b9250829190859081106108f157fe5b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790556001600160e01b031992909216825286905260409020805461ffff60a01b1916600160a01b61ffff8516021790555b6001600160a01b0384166000908152600186016020526040902080548061097a57fe5b60008281526020808220600860001990940193840401805463ffffffff600460078716026101000a0219169055919092556001600160e01b0319851682528690526040902080546001600160b01b0319169055806103b05760028501546001600160a01b03851660009081526001878101602052604090912001546000199091019061ffff16808214610a8e576000876002018381548110610a1857fe5b6000918252602090912001546002890180546001600160a01b039092169250829184908110610a4357fe5b600091825260208083209190910180546001600160a01b0319166001600160a01b0394851617905592909116815260018981019092526040902001805461ffff191661ffff83161790555b86600201805480610a9b57fe5b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b03881682526001898101909152604090912001805461ffff1916905550505050505050565b6001600160a01b03169052565b60008151808452610b12816020860160208601611009565b601f01601f19169290920160200192915050565b60008251610b38818460208701611009565b9190910192915050565b606080825284518282018190526000919060809081850190602080820287018401818b01875b84811015610bfa57898303607f19018652815180516001600160a01b03168452848101518985019060038110610b9a57fe5b858701526040918201519185018a9052815190819052908501908a90898601905b80831015610be55783516001600160e01b0319168252928701926001929092019190870190610bbb565b50978601979450505090830190600101610b68565b5050610c088289018b610aed565b8781036040890152610c1a818a610afa565b9b9a5050505050505050505050565b600060208252610c3c6020830184610afa565b9392505050565b6020808252603c908201527f4c69624469616d6f6e644375743a205f696e697420697320616464726573732860408201527f3029206275745f63616c6c64617461206973206e6f7420656d70747900000000606082015260800190565b60208082526026908201527f4c69624469616d6f6e644375743a205f696e69742066756e6374696f6e2072656040820152651d995c9d195960d21b606082015260800190565b6020808252602b908201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660408201526a1858d95d081d1bc818dd5d60aa1b606082015260800190565b60208082526037908201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360408201527f74696f6e207468617420646f65736e2774206578697374000000000000000000606082015260800190565b60208082526027908201527f4c69624469616d6f6e644375743a20496e636f727265637420466163657443756040820152663a20b1ba34b7b760c91b606082015260800190565b6020808252602c908201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260408201526b65206164647265737328302960a01b606082015260800190565b6020808252818101527f4469616d6f6e643a2046756e6374696f6e20646f6573206e6f74206578697374604082015260600190565b6020808252603d908201527f4c69624469616d6f6e644375743a205f63616c6c6461746120697320656d707460408201527f7920627574205f696e6974206973206e6f742061646472657373283029000000606082015260800190565b6020808252602e908201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560408201526d3a30b1363290333ab731ba34b7b760911b606082015260800190565b60208082526035908201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f6040820152746e207468617420616c72656164792065786973747360581b606082015260800190565b60208082526038908201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60408201527f6374696f6e20776974682073616d652066756e6374696f6e0000000000000000606082015260800190565b60208082526036908201527f4c69624469616d6f6e644375743a2052656d6f76652066616365742061646472604082015275657373206d757374206265206164647265737328302960501b606082015260800190565b60005b8381101561102457818101518382015260200161100c565b838111156105f6575050600091015256fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f6465a2646970667358221220043c177efb5eac6ee624fabfd8a1fb025490da2d22d3886abcbd9485dc3e506364736f6c63430007060033

Verified Source Code Full Match

Compiler: v0.7.6+commit.7338295f EVM: istanbul Optimization: Yes (200 runs)
Router.sol 42 lines
// SPDX-License-Identifier: Unlicense
pragma solidity 0.7.6;
pragma experimental ABIEncoderV2;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./interfaces/IDiamondLoupe.sol";
import "./interfaces/IDiamondCut.sol";
import "./interfaces/IERC165.sol";
import "./libraries/LibDiamond.sol";

contract Router {
    constructor(IDiamondCut.FacetCut[] memory _diamondCut) payable {
        LibDiamond.diamondCut(_diamondCut, address(0), new bytes(0));

        LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();

        // adding ERC165 data
        ds.supportedInterfaces[type(IERC165).interfaceId] = true;
        ds.supportedInterfaces[type(IDiamondCut).interfaceId] = true;
        ds.supportedInterfaces[type(IDiamondLoupe).interfaceId] = true;
    }

    // Find facet for function that is called and execute the
    // function if a facet is found and return any value.
    fallback() external {
        LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();
        address facet = ds.selectorToFacetAndPosition[msg.sig].facetAddress;
        require(facet != address(0), "Diamond: Function does not exist");
        assembly {
            calldatacopy(0, 0, calldatasize())
            let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)
            returndatacopy(0, 0, returndatasize())
            switch result
                case 0 {
                    revert(0, returndatasize())
                }
                default {
                    return(0, returndatasize())
                }
        }
    }
}
IERC165.sol 13 lines
// SPDX-License-Identifier: Unlicense
pragma solidity 0.7.6;
pragma experimental ABIEncoderV2;

interface IERC165 {
    /// @notice Query if a contract implements an interface
    /// @param interfaceId The interface identifier, as specified in ERC-165
    /// @dev Interface identification is specified in ERC-165. This function
    ///  uses less than 30,000 gas.
    /// @return `true` if the contract implements `interfaceID` and
    ///  `interfaceID` is not 0xffffffff, `false` otherwise
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
LibDiamond.sol 184 lines
// SPDX-License-Identifier: Unlicense
pragma solidity 0.7.6;
pragma experimental ABIEncoderV2;

import "../interfaces/IDiamondCut.sol";

library LibDiamond {
    bytes32 constant DIAMOND_STORAGE_POSITION = keccak256("diamond.standard.diamond.storage");

    struct FacetAddressAndPosition {
        address facetAddress;
        uint16 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array
    }

    struct FacetFunctionSelectors {
        bytes4[] functionSelectors;
        uint16 facetAddressPosition; // position of facetAddress in facetAddresses array
    }

    struct DiamondStorage {
        // maps function selector to the facet address and
        // the position of the selector in the facetFunctionSelectors.selectors array
        mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;
        // maps facet addresses to function selectors
        mapping(address => FacetFunctionSelectors) facetFunctionSelectors;
        // facet addresses
        address[] facetAddresses;
        // Used to query if a contract implements an interface.
        // Used to implement ERC-165.
        mapping(bytes4 => bool) supportedInterfaces;
    }

    function diamondStorage() internal pure returns (DiamondStorage storage ds) {
        bytes32 position = DIAMOND_STORAGE_POSITION;
        assembly {
            ds.slot := position
        }
    }

    event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);

    // Internal function version of diamondCut
    function diamondCut(
        IDiamondCut.FacetCut[] memory _diamondCut,
        address _init,
        bytes memory _calldata
    ) internal {
        for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {
            IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;
            if (action == IDiamondCut.FacetCutAction.Add) {
                addFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);
            } else if (action == IDiamondCut.FacetCutAction.Replace) {
                replaceFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);
            } else if (action == IDiamondCut.FacetCutAction.Remove) {
                removeFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);
            } else {
                revert("LibDiamondCut: Incorrect FacetCutAction");
            }
        }
        emit DiamondCut(_diamondCut, _init, _calldata);
        initializeDiamondCut(_init, _calldata);
    }

    function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {
        require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut");
        DiamondStorage storage ds = diamondStorage();
        // uint16 selectorCount = uint16(diamondStorage().selectors.length);
        require(_facetAddress != address(0), "LibDiamondCut: Add facet can't be address(0)");
        uint16 selectorPosition = uint16(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);
        // add new facet address if it does not exist
        if (selectorPosition == 0) {
            enforceHasContractCode(_facetAddress, "LibDiamondCut: New facet has no code");
            ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = uint16(ds.facetAddresses.length);
            ds.facetAddresses.push(_facetAddress);
        }
        for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {
            bytes4 selector = _functionSelectors[selectorIndex];
            address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;
            require(oldFacetAddress == address(0), "LibDiamondCut: Can't add function that already exists");
            addFunction(ds, selector, selectorPosition, _facetAddress);
            selectorPosition++;
        }
    }

    function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {
        require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut");
        DiamondStorage storage ds = diamondStorage();
        require(_facetAddress != address(0), "LibDiamondCut: Add facet can't be address(0)");
        uint16 selectorPosition = uint16(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);
        // add new facet address if it does not exist
        if (selectorPosition == 0) {
            enforceHasContractCode(_facetAddress, "LibDiamondCut: New facet has no code");
            ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = uint16(ds.facetAddresses.length);
            ds.facetAddresses.push(_facetAddress);
        }
        for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {
            bytes4 selector = _functionSelectors[selectorIndex];
            address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;
            require(oldFacetAddress != _facetAddress, "LibDiamondCut: Can't replace function with same function");
            removeFunction(ds, oldFacetAddress, selector);
            // add function
            addFunction(ds, selector, selectorPosition, _facetAddress);
            selectorPosition++;
        }
    }

    function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {
        require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut");
        DiamondStorage storage ds = diamondStorage();
        // if function does not exist then do nothing and return
        require(_facetAddress == address(0), "LibDiamondCut: Remove facet address must be address(0)");
        for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {
            bytes4 selector = _functionSelectors[selectorIndex];
            address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;
            removeFunction(ds, oldFacetAddress, selector);
        }
    }

    function addFunction(DiamondStorage storage ds, bytes4 _selector, uint16 _selectorPosition, address _facetAddress) internal {
        ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;
        ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);
        ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;
    }

    function removeFunction(DiamondStorage storage ds, address _facetAddress, bytes4 _selector) internal {
        require(_facetAddress != address(0), "LibDiamondCut: Can't remove function that doesn't exist");
        // an immutable function is a function defined directly in a diamond
        require(_facetAddress != address(this), "LibDiamondCut: Can't remove immutable function");
        // replace selector with last selector, then delete last selector
        uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;
        uint256 lastSelectorPosition = ds.facetFunctionSelectors[_facetAddress].functionSelectors.length - 1;
        // if not the same then replace _selector with lastSelector
        if (selectorPosition != lastSelectorPosition) {
            bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[lastSelectorPosition];
            ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;
            ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint16(selectorPosition);
        }
        // delete the last selector
        ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();
        delete ds.selectorToFacetAndPosition[_selector];

        // if no more selectors for facet address then delete the facet address
        if (lastSelectorPosition == 0) {
            // replace facet address with last facet address and delete last facet address
            uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;
            uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;
            if (facetAddressPosition != lastFacetAddressPosition) {
                address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];
                ds.facetAddresses[facetAddressPosition] = lastFacetAddress;
                ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = uint16(facetAddressPosition);
            }
            ds.facetAddresses.pop();
            delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;
        }
    }

    function initializeDiamondCut(address _init, bytes memory _calldata) internal {
        if (_init == address(0)) {
            require(_calldata.length == 0, "LibDiamondCut: _init is address(0) but_calldata is not empty");
        } else {
            require(_calldata.length > 0, "LibDiamondCut: _calldata is empty but _init is not address(0)");
            if (_init != address(this)) {
                enforceHasContractCode(_init, "LibDiamondCut: _init address has no code");
            }
            (bool success, bytes memory error) = _init.delegatecall(_calldata);
            if (!success) {
                if (error.length > 0) {
                    // bubble up the error
                    revert(string(error));
                } else {
                    revert("LibDiamondCut: _init function reverted");
                }
            }
        }
    }

    function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {
        uint256 contractSize;
        assembly {
            contractSize := extcodesize(_contract)
        }
        require(contractSize > 0, _errorMessage);
    }
}
IDiamondCut.sol 30 lines
// SPDX-License-Identifier: Unlicense
pragma solidity 0.7.6;
pragma experimental ABIEncoderV2;

interface IDiamondCut {
    enum FacetCutAction {Add, Replace, Remove}
    // Add=0, Replace=1, Remove=2

    struct FacetCut {
        address facetAddress;
        FacetCutAction action;
        bytes4[] functionSelectors;
    }

    /// @notice Add/replace/remove any number of functions and optionally execute
    ///         a function with delegatecall
    /// @param _diamondCut Contains the facet addresses and function selectors
    /// @param _init The address of the contract or facet to execute _calldata
    /// @param _calldata A function call, including function selector and arguments
    ///                  _calldata is executed with delegatecall on _init
    /// @param _signatures The signatures of between n/2 and n validators for this upgrade
    function diamondCut(
        FacetCut[] calldata _diamondCut,
        address _init,
        bytes calldata _calldata,
        bytes[] memory _signatures
    ) external;

    event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);
}
IDiamondLoupe.sol 34 lines
// SPDX-License-Identifier: Unlicense
pragma solidity 0.7.6;
pragma experimental ABIEncoderV2;

// A loupe is a small magnifying glass used to look at diamonds.
// These functions look at diamonds
interface IDiamondLoupe {
    /// These functions are expected to be called frequently
    /// by tools.

    struct Facet {
        address facetAddress;
        bytes4[] functionSelectors;
    }

    /// @notice Gets all facet addresses and their four byte function selectors.
    /// @return facets_ Facet
    function facets() external view returns (Facet[] memory facets_);

    /// @notice Gets all the function selectors supported by a specific facet.
    /// @param _facet The facet address.
    /// @return facetFunctionSelectors_
    function facetFunctionSelectors(address _facet) external view returns (bytes4[] memory facetFunctionSelectors_);

    /// @notice Get all the facet addresses used by a diamond.
    /// @return facetAddresses_
    function facetAddresses() external view returns (address[] memory facetAddresses_);

    /// @notice Gets the facet that supports the given selector.
    /// @dev If facet is not found return address(0).
    /// @param _functionSelector The function selector.
    /// @return facetAddress_ The facet address.
    function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_);
}
IERC20.sol 77 lines
// SPDX-License-Identifier: MIT

pragma solidity ^0.7.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

Recent Transactions

No transactions found for this address