// SPDX-License-Identifier: MIT
// SPDX-FileCopyrightText: Copyright (C) 2022 Spanning Labs Inc.
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import "@openzeppelin/contracts/utils/Context.sol";
import "./SpanningERC20Container.sol";
/**
* @dev Implementation of the {ISpanningERC20} interface.
*/
contract SpanningERC20 is SpanningERC20Container {
// This allows us to efficiently unpack data in our address specification.
using SpanningAddress for bytes32;
/**
* @dev Creates the instance and assigns required values.
*
* @param name - Desired name for the token
* @param symbol - Desired symbol for the token
* @param delegate - Legacy (local) address for the Spanning Delegate
*/
constructor(
string memory name,
string memory symbol,
address delegate
) SpanningERC20Container(name, symbol, delegate) {}
/**
* @dev Function override that hooks into the `mint` lifecycle
*
* @param senderAddress - Unused
* @param receiverAddress - Address to receive the minted tokens
* @param amount - Amount of token to mint
*
* TODO(ENG-145): FIX overflows
*/
function _duringTokenMint(
bytes32 senderAddress,
bytes32 receiverAddress,
uint256 amount
) internal virtual override {
totalSupply_ += amount;
balances_[receiverAddress] += amount;
}
/**
* @dev Function override that hooks into the `burn` lifecycle
*
* @param senderAddress - Address that the token is burned from
* @param receiverAddress - Unused
* @param amount - Amount of token to burn
*/
function _duringTokenBurn(
bytes32 senderAddress,
bytes32 receiverAddress,
uint256 amount
) internal virtual override {
uint256 accountBalance = balances_[senderAddress];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
unchecked {
balances_[senderAddress] = accountBalance - amount;
}
totalSupply_ -= amount;
}
/**
* @dev Function override that hooks into the `transfer` lifecycle
*
* @param senderAddress - Address initiating the transfer
* @param receiverAddress - Address to receive the transfer
* @param amount - Amount of token to transfer
*/
function _duringTokenTransfer(
bytes32 senderAddress,
bytes32 receiverAddress,
uint256 amount
) internal virtual override {
uint256 senderBalance = balances_[senderAddress];
require(
senderBalance >= amount,
"ERC20: transfer amount exceeds balance"
);
unchecked {
balances_[senderAddress] = senderBalance - amount;
}
balances_[receiverAddress] += amount;
}
/**
* @dev Function override that hooks into the `approve` lifecycle
*
* @param senderAddress - Address of the allowance sender
* @param receiverAddress - Address of the allowance receiver
* @param amount - Amount of allowance to issue
*/
function _duringTokenApprove(
bytes32 senderAddress,
bytes32 receiverAddress,
uint256 amount
) internal virtual override {
allowances_[senderAddress][receiverAddress] = amount;
}
}
|