// SPDX-License-Identifier: MIT pragma solidity 0.8.19; import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol"; import "../interfaces/IPropel.sol"; import "../interfaces/IEsPropel.sol"; import "../dependencies/PropelOwnable.sol"; contract Propel is ERC20Burnable, ERC20Permit, PropelOwnable, IPropel { IEsPropel public esPropel; address public vest; uint256 public immutable MaxCap = 1000000000 ether; constructor(IPropelCore _propelCore, IEsPropel _esPropel, address _vest) ERC20("Propel Coin", "Propel") ERC20Permit("Propel Coin") PropelOwnable(_propelCore) { esPropel = _esPropel; vest = _vest; } function mint(address account, uint256 amount) external onlyOwner { require(totalSupply() + esPropel.totalSupply() + amount <= MaxCap, "Propel: exceeds MaxCap"); _mint(account, amount); } function mintEsPropel(address account, uint256 amount) external onlyOwner { require(totalSupply() + esPropel.totalSupply() + amount <= MaxCap, "Propel: exceeds MaxCap"); esPropel.mint(account, amount); } function propel2EsPropel(address account, uint256 amount) external override { _burn(msg.sender, amount); esPropel.mint(account, amount); emit PropelToEsPropel(account, amount); } function esPropel2Propel(address account, uint256 amount) external override { require(msg.sender == vest, "Propel: Caller is not Vest"); esPropel.burnFromPropel(msg.sender, amount); _mint(account, amount); emit EsPropelToPropel(account, amount); } function burn(uint256 amount) public override(ERC20Burnable, IPropel) { ERC20Burnable.burn(amount); } function burnFrom(address account, uint256 amount) public override(ERC20Burnable, IPropel) { ERC20Burnable.burnFrom(account, amount); } }