// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
/**
* @title BOSAGORA Token
* @dev Implementation of the BOSAGORA token with scheduled minting based on yearly timestamps.
*
* This contract implements the BOSAGORA token with the following features:
* - Fixed maximum supply of 4.95 billion BOA tokens
* - 7 decimal places
* - Scheduled minting over 128 years based on predefined deadlines and cumulative limits.
* - Minting up to the yearly limit targets a specific asset account.
* - Permissionless minting trigger (anyone can call mint after conditions are met).
* - No ownership or administrative functions after deployment.
*/
contract BOSAGORA is ERC20 {
/*
* Constants
*/
string private constant NAME = "BOSAGORA";
string private constant SYMBOL = "BOA";
uint8 private constant DECIMALS = 7;
uint256 public constant MAX_SUPPLY = 4_950_000_000 * 10 ** DECIMALS;
// --- Minting Schedule Constants (128 Years) ---
// Starts from 2022-12-31 UTC
uint256[128] private YEARLY_DEADLINE_TIMESTAMPS = [
1672444800, // 2022-12-31
1703980800, // 2023-12-31
1735603200, // 2024-12-31
1767139200, // 2025-12-31
1798675200, // 2026-12-31
1830211200, // 2027-12-31
1861833600, // 2028-12-31
1893369600, // 2029-12-31
1924905600, // 2030-12-31
1956441600, // 2031-12-31
1988064000, // 2032-12-31
2019600000, // 2033-12-31
2051136000, // 2034-12-31
2082672000, // 2035-12-31
2114294400, // 2036-12-31
2145830400, // 2037-12-31
2177366400, // 2038-12-31
2208902400, // 2039-12-31
2240524800, // 2040-12-31
2272060800, // 2041-12-31
2303596800, // 2042-12-31
2335132800, // 2043-12-31
2366755200, // 2044-12-31
2398291200, // 2045-12-31
2429827200, // 2046-12-31
2461363200, // 2047-12-31
2492985600, // 2048-12-31
2524521600, // 2049-12-31
2556057600, // 2050-12-31
2587593600, // 2051-12-31
2619216000, // 2052-12-31
2650752000, // 2053-12-31
2682288000, // 2054-12-31
2713824000, // 2055-12-31
2745446400, // 2056-12-31
2776982400, // 2057-12-31
2808518400, // 2058-12-31
2840054400, // 2059-12-31
2871676800, // 2060-12-31
2903212800, // 2061-12-31
2934748800, // 2062-12-31
2966284800, // 2063-12-31
2997907200, // 2064-12-31
3029443200, // 2065-12-31
3060979200, // 2066-12-31
3092515200, // 2067-12-31
3124137600, // 2068-12-31
3155673600, // 2069-12-31
3187209600, // 2070-12-31
3218745600, // 2071-12-31
3250368000, // 2072-12-31
3281904000, // 2073-12-31
3313440000, // 2074-12-31
3344976000, // 2075-12-31
3376598400, // 2076-12-31
3408134400, // 2077-12-31
3439670400, // 2078-12-31
3471206400, // 2079-12-31
3502828800, // 2080-12-31
3534364800, // 2081-12-31
3565900800, // 2082-12-31
3597436800, // 2083-12-31
3629059200, // 2084-12-31
3660595200, // 2085-12-31
3692131200, // 2086-12-31
3723667200, // 2087-12-31
3755289600, // 2088-12-31
3786825600, // 2089-12-31
3818361600, // 2090-12-31
3849897600, // 2091-12-31
3881520000, // 2092-12-31
3913056000, // 2093-12-31
3944592000, // 2094-12-31
3976128000, // 2095-12-31
4007750400, // 2096-12-31
4039286400, // 2097-12-31
4070822400, // 2098-12-31
4102358400, // 2099-12-31
4133894400, // 2100-12-31
4165430400, // 2101-12-31
4196966400, // 2102-12-31
4228502400, // 2103-12-31
4260124800, // 2104-12-31
4291660800, // 2105-12-31
4323196800, // 2106-12-31
4354732800, // 2107-12-31
4386355200, // 2108-12-31
4417891200, // 2109-12-31
4449427200, // 2110-12-31
4480963200, // 2111-12-31
4512585600, // 2112-12-31
4544121600, // 2113-12-31
4575657600, // 2114-12-31
4607193600, // 2115-12-31
4638816000, // 2116-12-31
4670352000, // 2117-12-31
4701888000, // 2118-12-31
4733424000, // 2119-12-31
4765046400, // 2120-12-31
4796582400, // 2121-12-31
4828118400, // 2122-12-31
4859654400, // 2123-12-31
4891276800, // 2124-12-31
4922812800, // 2125-12-31
4954348800, // 2126-12-31
4985884800, // 2127-12-31
5017507200, // 2128-12-31
5049043200, // 2129-12-31
5080579200, // 2130-12-31
5112115200, // 2131-12-31
5143737600, // 2132-12-31
5175273600, // 2133-12-31
5206809600, // 2134-12-31
5238345600, // 2135-12-31
5269968000, // 2136-12-31
5301504000, // 2137-12-31
5333040000, // 2138-12-31
5364576000, // 2139-12-31
5396198400, // 2140-12-31
5427734400, // 2141-12-31
5459270400, // 2142-12-31
5490806400, // 2143-12-31
5522428800, // 2144-12-31
5553964800, // 2145-12-31
5585500800, // 2146-12-31
5617036800, // 2147-12-31
5648659200, // 2148-12-31
5680195200 // 2149-12-31
];
uint256[128] private YEARLY_CUMULATIVE_SUPPLY_LIMITS = [
809_510_400 * 10 ** DECIMALS, // 2022-12-31
1_168_426_094 * 10 ** DECIMALS, // 2023-12-31
1_526_755_093 * 10 ** DECIMALS, // 2024-12-31
1_884_505_300 * 10 ** DECIMALS, // 2025-12-31
2_241_684_510 * 10 ** DECIMALS, // 2026-12-31
2_506_140_416 * 10 ** DECIMALS, // 2027-12-31
2_546_840_604 * 10 ** DECIMALS, // 2028-12-31
2_586_992_561 * 10 ** DECIMALS, // 2029-12-31
2_626_603_671 * 10 ** DECIMALS, // 2030-12-31
2_665_681_220 * 10 ** DECIMALS, // 2031-12-31
2_704_232_394 * 10 ** DECIMALS, // 2032-12-31
2_742_264_284 * 10 ** DECIMALS, // 2033-12-31
2_779_783_884 * 10 ** DECIMALS, // 2034-12-31
2_816_798_095 * 10 ** DECIMALS, // 2035-12-31
2_853_313_724 * 10 ** DECIMALS, // 2036-12-31
2_889_337_489 * 10 ** DECIMALS, // 2037-12-31
2_924_876_013 * 10 ** DECIMALS, // 2038-12-31
2_959_935_833 * 10 ** DECIMALS, // 2039-12-31
2_994_523_397 * 10 ** DECIMALS, // 2040-12-31
3_028_645_067 * 10 ** DECIMALS, // 2041-12-31
3_062_307_118 * 10 ** DECIMALS, // 2042-12-31
3_095_515_741 * 10 ** DECIMALS, // 2043-12-31
3_128_277_044 * 10 ** DECIMALS, // 2044-12-31
3_160_597_052 * 10 ** DECIMALS, // 2045-12-31
3_192_481_710 * 10 ** DECIMALS, // 2046-12-31
3_223_936_881 * 10 ** DECIMALS, // 2047-12-31
3_254_968_351 * 10 ** DECIMALS, // 2048-12-31
3_285_581_828 * 10 ** DECIMALS, // 2049-12-31
3_315_782_941 * 10 ** DECIMALS, // 2050-12-31
3_345_577_244 * 10 ** DECIMALS, // 2051-12-31
3_374_970_219 * 10 ** DECIMALS, // 2052-12-31
3_403_967_270 * 10 ** DECIMALS, // 2053-12-31
3_432_573_731 * 10 ** DECIMALS, // 2054-12-31
3_460_794_863 * 10 ** DECIMALS, // 2055-12-31
3_488_635_856 * 10 ** DECIMALS, // 2056-12-31
3_516_101_831 * 10 ** DECIMALS, // 2057-12-31
3_543_197_839 * 10 ** DECIMALS, // 2058-12-31
3_569_928_864 * 10 ** DECIMALS, // 2059-12-31
3_596_299_823 * 10 ** DECIMALS, // 2060-12-31
3_622_315_564 * 10 ** DECIMALS, // 2061-12-31
3_647_980_873 * 10 ** DECIMALS, // 2062-12-31
3_673_300_471 * 10 ** DECIMALS, // 2063-12-31
3_698_279_014 * 10 ** DECIMALS, // 2064-12-31
3_722_921_095 * 10 ** DECIMALS, // 2065-12-31
3_747_231_248 * 10 ** DECIMALS, // 2066-12-31
3_771_213_943 * 10 ** DECIMALS, // 2067-12-31
3_794_873_591 * 10 ** DECIMALS, // 2068-12-31
3_818_214_544 * 10 ** DECIMALS, // 2069-12-31
3_841_241_094 * 10 ** DECIMALS, // 2070-12-31
3_863_957_477 * 10 ** DECIMALS, // 2071-12-31
3_886_367_869 * 10 ** DECIMALS, // 2072-12-31
3_908_476_394 * 10 ** DECIMALS, // 2073-12-31
3_930_287_117 * 10 ** DECIMALS, // 2074-12-31
3_951_804_050 * 10 ** DECIMALS, // 2075-12-31
3_973_031_149 * 10 ** DECIMALS, // 2076-12-31
3_993_972_320 * 10 ** DECIMALS, // 2077-12-31
4_014_631_413 * 10 ** DECIMALS, // 2078-12-31
4_035_012_227 * 10 ** DECIMALS, // 2079-12-31
4_055_118_513 * 10 ** DECIMALS, // 2080-12-31
4_074_953_966 * 10 ** DECIMALS, // 2081-12-31
4_094_522_236 * 10 ** DECIMALS, // 2082-12-31
4_113_826_922 * 10 ** DECIMALS, // 2083-12-31
4_132_871_573 * 10 ** DECIMALS, // 2084-12-31
4_151_659_693 * 10 ** DECIMALS, // 2085-12-31
4_170_194_737 * 10 ** DECIMALS, // 2086-12-31
4_188_480_114 * 10 ** DECIMALS, // 2087-12-31
4_206_519_187 * 10 ** DECIMALS, // 2088-12-31
4_224_315_273 * 10 ** DECIMALS, // 2089-12-31
4_241_871_647 * 10 ** DECIMALS, // 2090-12-31
4_259_191_536 * 10 ** DECIMALS, // 2091-12-31
4_276_278_126 * 10 ** DECIMALS, // 2092-12-31
4_293_134_559 * 10 ** DECIMALS, // 2093-12-31
4_309_763_937 * 10 ** DECIMALS, // 2094-12-31
4_326_169_316 * 10 ** DECIMALS, // 2095-12-31
4_342_353_716 * 10 ** DECIMALS, // 2096-12-31
4_358_320_111 * 10 ** DECIMALS, // 2097-12-31
4_374_071_439 * 10 ** DECIMALS, // 2098-12-31
4_389_610_597 * 10 ** DECIMALS, // 2099-12-31
4_404_940_442 * 10 ** DECIMALS, // 2100-12-31
4_420_063_795 * 10 ** DECIMALS, // 2101-12-31
4_434_983_435 * 10 ** DECIMALS, // 2102-12-31
4_449_702_108 * 10 ** DECIMALS, // 2103-12-31
4_464_222_521 * 10 ** DECIMALS, // 2104-12-31
4_478_547_344 * 10 ** DECIMALS, // 2105-12-31
4_492_679_211 * 10 ** DECIMALS, // 2106-12-31
4_506_620_722 * 10 ** DECIMALS, // 2107-12-31
4_520_374_441 * 10 ** DECIMALS, // 2108-12-31
4_533_942_897 * 10 ** DECIMALS, // 2109-12-31
4_547_328_586 * 10 ** DECIMALS, // 2110-12-31
4_560_533_970 * 10 ** DECIMALS, // 2111-12-31
4_573_561_478 * 10 ** DECIMALS, // 2112-12-31
4_586_413_505 * 10 ** DECIMALS, // 2113-12-31
4_599_092_415 * 10 ** DECIMALS, // 2114-12-31
4_611_600_540 * 10 ** DECIMALS, // 2115-12-31
4_623_940_181 * 10 ** DECIMALS, // 2116-12-31
4_636_113_606 * 10 ** DECIMALS, // 2117-12-31
4_648_123_056 * 10 ** DECIMALS, // 2118-12-31
4_659_970_738 * 10 ** DECIMALS, // 2119-12-31
4_671_658_833 * 10 ** DECIMALS, // 2120-12-31
4_683_189_488 * 10 ** DECIMALS, // 2121-12-31
4_694_564_826 * 10 ** DECIMALS, // 2122-12-31
4_705_786_938 * 10 ** DECIMALS, // 2123-12-31
4_716_857_887 * 10 ** DECIMALS, // 2124-12-31
4_727_779_712 * 10 ** DECIMALS, // 2125-12-31
4_738_554_419 * 10 ** DECIMALS, // 2126-12-31
4_749_183_991 * 10 ** DECIMALS, // 2127-12-31
4_759_670_383 * 10 ** DECIMALS, // 2128-12-31
4_770_015_523 * 10 ** DECIMALS, // 2129-12-31
4_780_221_313 * 10 ** DECIMALS, // 2130-12-31
4_790_289_632 * 10 ** DECIMALS, // 2131-12-31
4_800_222_331 * 10 ** DECIMALS, // 2132-12-31
4_810_021_236 * 10 ** DECIMALS, // 2133-12-31
4_819_688_150 * 10 ** DECIMALS, // 2134-12-31
4_829_224_851 * 10 ** DECIMALS, // 2135-12-31
4_838_633_092 * 10 ** DECIMALS, // 2136-12-31
4_847_914_604 * 10 ** DECIMALS, // 2137-12-31
4_857_071_095 * 10 ** DECIMALS, // 2138-12-31
4_866_104_247 * 10 ** DECIMALS, // 2139-12-31
4_875_015_723 * 10 ** DECIMALS, // 2140-12-31
4_883_807_161 * 10 ** DECIMALS, // 2141-12-31
4_892_480_178 * 10 ** DECIMALS, // 2142-12-31
4_901_036_370 * 10 ** DECIMALS, // 2143-12-31
4_909_477_311 * 10 ** DECIMALS, // 2144-12-31
4_917_804_551 * 10 ** DECIMALS, // 2145-12-31
4_926_019_624 * 10 ** DECIMALS, // 2146-12-31
4_934_124_040 * 10 ** DECIMALS, // 2147-12-31
4_942_119_289 * 10 ** DECIMALS, // 2148-12-31
MAX_SUPPLY // 2149-12-31
];
// --- End Minting Schedule Constants ---
/*
* Storage
*/
address public immutable assetAccount; // Address that receives all minted tokens.
// Index of the next minting period deadline in the timestamp array.
uint256 public nextMintingPeriodIndex;
/*
* Events
*/
/**
* @notice Emitted when tokens are created according to the schedule.
* @param account The account that received the minted tokens (always assetAccount).
* @param amount The amount of tokens minted.
* @param periodIndex The index of the minting period that was just completed.
*/
event ScheduledTokensMinted(address indexed account, uint256 amount, uint256 periodIndex);
/*
* Public functions
*/
/**
* @dev Initializes the contract, setting the asset account address.
* @param account The address that will receive all minted tokens.
*
* Requirements:
* - The account cannot be the zero address.
*/
constructor(address account) ERC20(NAME, SYMBOL) {
require(account != address(0), "BOSAGORA: Asset account is zero address");
assetAccount = account;
}
/**
* @dev Mints new tokens according to the schedule if the current timestamp has passed the next deadline.
* Can be called by anyone.
* Mints tokens up to the cumulative limit defined for the passed deadline.
*
* Requirements:
* - The current timestamp must be greater than or equal to the timestamp at `nextMintingPeriodIndex`.
* - `nextMintingPeriodIndex` must be within the bounds of the schedule arrays.
* - Current total supply must be less than the limit for the completed period.
*
* Emits a {ScheduledTokensMinted} event if tokens are minted.
*/
function mint() external {
uint256 currentIndex = nextMintingPeriodIndex;
require(currentIndex < 128, "BOSAGORA: Minting schedule finished");
// Access storage array directly
uint256 currentDeadline = YEARLY_DEADLINE_TIMESTAMPS[currentIndex];
require(block.timestamp >= currentDeadline, "BOSAGORA: Minting period not yet finished");
// Access storage array directly
uint256 targetSupply = YEARLY_CUMULATIVE_SUPPLY_LIMITS[currentIndex];
uint256 currentSupply = totalSupply();
if (currentSupply >= targetSupply) {
nextMintingPeriodIndex = currentIndex + 1;
return;
}
uint256 amount = targetSupply - currentSupply;
if (amount > 0) {
nextMintingPeriodIndex = currentIndex + 1;
_mint(assetAccount, amount);
emit ScheduledTokensMinted(assetAccount, amount, currentIndex);
} else {
nextMintingPeriodIndex = currentIndex + 1;
}
}
/**
* @dev Returns the number of decimals.
*/
function decimals() public view virtual override returns (uint8) {
return DECIMALS;
}
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)
pragma solidity ^0.8.0;
import "./IERC20.sol";
import "./extensions/IERC20Metadata.sol";
import "../../utils/Context.sol";
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
* For a generic mechanism see {ERC20PresetMinterPauser}.
*
* TIP: For a detailed writeup see our guide
* https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* The default value of {decimals} is 18. To change this, you should override
* this function so it returns a different value.
*
* We have followed general OpenZeppelin Contracts guidelines: functions revert
* instead returning `false` on failure. This behavior is nonetheless
* conventional and does not conflict with the expectations of ERC20
* applications.
*
* Additionally, an {Approval} event is emitted on calls to {transferFrom}.
* This allows applications to reconstruct the allowance for all accounts just
* by listening to said events. Other implementations of the EIP may not emit
* these events, as it isn't required by the specification.
*
* Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
* functions have been added to mitigate the well-known issues around setting
* allowances. See {IERC20-approve}.
*/
contract ERC20 is Context, IERC20, IERC20Metadata {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
/**
* @dev Sets the values for {name} and {symbol}.
*
* All two of these values are immutable: they can only be set once during
* construction.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5.05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the default value returned by this function, unless
* it's overridden.
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view virtual override returns (uint8) {
return 18;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/
function transfer(address to, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_transfer(owner, to, amount);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
* `transferFrom`. This is semantically equivalent to an infinite approval.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_approve(owner, spender, amount);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20}.
*
* NOTE: Does not update the allowance if the current allowance
* is the maximum `uint256`.
*
* Requirements:
*
* - `from` and `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
* - the caller must have allowance for ``from``'s tokens of at least
* `amount`.
*/
function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, amount);
_transfer(from, to, amount);
return true;
}
/**
* @dev Atomically increases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, allowance(owner, spender) + addedValue);
return true;
}
/**
* @dev Atomically decreases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
address owner = _msgSender();
uint256 currentAllowance = allowance(owner, spender);
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(owner, spender, currentAllowance - subtractedValue);
}
return true;
}
/**
* @dev Moves `amount` of tokens from `from` to `to`.
*
* This internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
*/
function _transfer(address from, address to, uint256 amount) internal virtual {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(from, to, amount);
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
// Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by
// decrementing then incrementing.
_balances[to] += amount;
}
emit Transfer(from, to, amount);
_afterTokenTransfer(from, to, amount);
}
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply += amount;
unchecked {
// Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.
_balances[account] += amount;
}
emit Transfer(address(0), account, amount);
_afterTokenTransfer(address(0), account, amount);
}
/**
* @dev Destroys `amount` tokens from `account`, reducing the
* total supply.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
unchecked {
_balances[account] = accountBalance - amount;
// Overflow not possible: amount <= accountBalance <= totalSupply.
_totalSupply -= amount;
}
emit Transfer(account, address(0), amount);
_afterTokenTransfer(account, address(0), amount);
}
/**
* @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*/
function _approve(address owner, address spender, uint256 amount) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
/**
* @dev Updates `owner` s allowance for `spender` based on spent `amount`.
*
* Does not update the allowance amount in case of infinite allowance.
* Revert if not enough allowance is available.
*
* Might emit an {Approval} event.
*/
function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
require(currentAllowance >= amount, "ERC20: insufficient allowance");
unchecked {
_approve(owner, spender, currentAllowance - amount);
}
}
}
/**
* @dev Hook that is called before any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}
/**
* @dev Hook that is called after any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* has been transferred to `to`.
* - when `from` is zero, `amount` tokens have been minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens have been burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @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);
/**
* @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 `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount) external returns (bool);
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*
* _Available since v4.1._
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}
{
"compilationTarget": {
"boa-contracts/contracts/BOSAGORA.sol": "BOSAGORA"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 2000
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"account","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"periodIndex","type":"uint256"}],"name":"ScheduledTokensMinted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"assetAccount","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextMintingPeriodIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]