-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement Lisk L1 token smart contract (#13)
* L1LiskToken is ERC20 contract * Unauthorized error * Ownable contract * L1LiskToken is Ownable * forge install: openzeppelin-solidity solc-nightly * BurnerRole contract * L1LiskToken maintains burners through BurnerRole contract * L1LiskToken allows burners to burn their tokens * L1LiskToken is ERC20Permit contract * L1LiskToken is Ownable from openzeppelin-contracts * 🔥 Removes Ownable contract * ♻️ ✅ BurnerRole declares and throws UnauthorizedBurnerAccount error * 🔥 Removes Errors.sol * L1LiskToken maintains burners * 🔥 Removes BurnerRole contract * L1LiskToken is ERC20Burnable * ✅ L1LiskToken.permit * ✅ L1LiskToken is AccessControl * ♻️ ✅ * L1LiskToken maintains owner role * Replaces OWNER_ROLE with DEFAULT_ADMIN_ROLE and removes owner() * Increases total supply to 300 million * Adds transferOwnership * Verifies if deployer is owner and not a burner and total supply is 300 million * ♻️ L1LiskToken declarations * ♻️ Replaces _msgSender() with msg.sender * ♻️ Sets DEFAULT_ADMIN_ROLE as the roleAdmin for BURNER_ROLE * ♻️ Removes getBurnerRole() for BURNER_ROLE() ✅ Removes defaultAdminRole for DEFAULT_ADMIN_ROLE() * ✅ Adds assertions for test_Initialize * ✅ Owner is not a burner * ♻️ ✅ Rearranges imports * ✅ Adds assertions * ✅ Only burner can burn from an account * Transfers ownership of L1LiskToken contract to configured address after deployment * ♻️ ✅ 🔥 Removes duplicate SigUtils * Updates script/L1LiskToken.s.sol Co-authored-by: Matjaz Verbole <[email protected]> * ♻️ L1LiskToken script * ♻️ ✅ Renames test methods for L1LiskToken * 📝 L1LiskToken * 📝 Updates renounceBurner NatSpec. Co-authored-by: Matjaz Verbole <[email protected]> * 📝 L1LiskTokenScript * 📝 L1LiskTokenScript Co-authored-by: Matjaz Verbole <[email protected]> * 📝 L1LiskTokenScript * ♻️ Removes call to _setRoleAdmin in ERC20 constructor --------- Co-authored-by: Matjaz Verbole <[email protected]>
- Loading branch information
Showing
7 changed files
with
241 additions
and
127 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Submodule openzeppelin-contracts-upgradeable
deleted from
625fb3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,71 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity 0.8.21; | ||
|
||
import { ERC20Upgradeable } from "@openzeppelin-upgradeable/contracts/token/ERC20/ERC20Upgradeable.sol"; | ||
import { Initializable } from "@openzeppelin-upgradeable/contracts/proxy/utils/Initializable.sol"; | ||
import { OwnableUpgradeable } from "@openzeppelin-upgradeable/contracts/access/OwnableUpgradeable.sol"; | ||
import { UUPSUpgradeable } from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol"; | ||
import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; | ||
|
||
contract UUPSProxy is ERC1967Proxy { | ||
constructor(address _implementation, bytes memory _data) ERC1967Proxy(_implementation, _data) { } | ||
} | ||
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; | ||
import { ERC20Burnable } from "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol"; | ||
import { ERC20Permit } from "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol"; | ||
import { AccessControl } from "@openzeppelin/contracts/access/AccessControl.sol"; | ||
|
||
contract L1LiskToken is Initializable, ERC20Upgradeable, OwnableUpgradeable, UUPSUpgradeable { | ||
/// @title L1LiskToken | ||
/// @notice L1LiskToken is an implementation of ERC20 token and is an extension of AccessControl, ERC20Permit and | ||
/// ERC20Burnable token contracts. | ||
/// It maintains the ownership of the deployed contract and only allows the owners to transfer the ownership. | ||
/// L1LiskToken's only allows burners to burn the total supply and only the owner manages burner accounts. | ||
contract L1LiskToken is ERC20Burnable, AccessControl, ERC20Permit { | ||
/// @notice Name of the token. | ||
string private constant NAME = "Lisk"; | ||
|
||
/// @notice Symbol of the token. | ||
string private constant SYMBOL = "LSK"; | ||
uint256 private constant TOTAL_SUPPLY = 200_000_000 * 10 ** 18; //200 million LSK tokens | ||
|
||
constructor() { | ||
_disableInitializers(); | ||
} | ||
/// @notice Total supply of the token. | ||
uint256 private constant TOTAL_SUPPLY = 300_000_000 * 10 ** 18; //300 million LSK tokens | ||
|
||
/// @notice Burner role. | ||
bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE"); | ||
|
||
function initialize() public initializer { | ||
__ERC20_init(NAME, SYMBOL); | ||
/// @notice Constructs the L1LiskToken contract. | ||
constructor() ERC20(NAME, SYMBOL) ERC20Permit(NAME) { | ||
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender); | ||
_mint(msg.sender, TOTAL_SUPPLY); | ||
__Ownable_init(msg.sender); | ||
} | ||
|
||
function _authorizeUpgrade(address newImplementation) internal override onlyOwner { } | ||
/// @notice Allows the owner to transfer the ownership of the contract. | ||
/// @param account The new owner of the contract. | ||
function transferOwnership(address account) public onlyRole(DEFAULT_ADMIN_ROLE) { | ||
_grantRole(DEFAULT_ADMIN_ROLE, account); | ||
_revokeRole(DEFAULT_ADMIN_ROLE, msg.sender); | ||
} | ||
|
||
/// @notice Verifies if an account is a burner. | ||
/// @param account Account to be verified. | ||
/// @return Whether or not the provided account is a burner. | ||
function isBurner(address account) public view returns (bool) { | ||
return hasRole(BURNER_ROLE, account); | ||
} | ||
|
||
/// @notice Allows the owner to grant burner role to an account. | ||
/// @param account Account to be added as a burner. | ||
function addBurner(address account) public onlyRole(DEFAULT_ADMIN_ROLE) { | ||
_grantRole(BURNER_ROLE, account); | ||
} | ||
|
||
/// @notice Allows the owner to revoke burner role from an account. | ||
/// @param account Account to be removed as a burner. | ||
function renounceBurner(address account) public onlyRole(DEFAULT_ADMIN_ROLE) { | ||
_revokeRole(BURNER_ROLE, account); | ||
} | ||
|
||
/// @notice Allows a burner to burn token. | ||
/// @param value Amount to be burned. | ||
function burn(uint256 value) public override onlyRole(BURNER_ROLE) { | ||
super.burn(value); | ||
} | ||
|
||
/// @notice Allows a burner to burn its allowance from an account. | ||
/// @param account Account to burn tokens from. | ||
/// @param value Amount to burned. | ||
function burnFrom(address account, uint256 value) public override onlyRole(BURNER_ROLE) { | ||
super.burnFrom(account, value); | ||
} | ||
} |
Oops, something went wrong.