abstract contract Context {
    // The reason for _msgSender() here is that if you instead reference msg.sender later (say, in the transfer() function),
    // then msg.sender might not be the actual address that sent the transaction, since there's several 
    // meta-transactions that happen within transfer() and we need to accurately define the sender in that function.
    // See https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Context.sol
    // and https://docs.soliditylang.org/en/develop/units-and-global-variables.html?highlight=msg.sender#block-and-transaction-properties
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }
    // Don't need the _msgData() function from OpenZeppelin's Context.sol here since we never use it or msg.data.
}
function _msgSender() internal view virtual returns (address) {
    return msg.sender;
}

// The reason for _msgSender() here is that if you instead reference msg.sender later (say, in the transfer() function),
// then msg.sender might not be the actual address that sent the transaction, since there's several 
// meta-transactions that happen within transfer() and we need to accurately define the sender in that function.
// See https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Context.sol
// and https://docs.soliditylang.org/en/develop/units-and-global-variables.html?highlight=msg.sender#block-and-transaction-properties