-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #58 from primevprotocol/whitelist-contract
Whitelist contract
- Loading branch information
Showing
4 changed files
with
164 additions
and
2 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// SPDX-License-Identifier: BSL 1.1 | ||
pragma solidity ^0.8.15; | ||
|
||
// Contract that allows an admin to add/remove addresses from the whitelist, | ||
// and allows whitelisted addresses to mint/burn native tokens. | ||
contract Whitelist { | ||
address public admin; | ||
mapping(address => bool) public whitelistedAddresses; | ||
|
||
// Mint/burn precompile addresses. | ||
// See: https://github.com/primevprotocol/go-ethereum/blob/03ae168c6ac15dda8c5a3f123e2b9f3350aad613/core/vm/contracts.go | ||
address constant MINT = address(0x89); | ||
address constant BURN = address(0x90); | ||
|
||
constructor(address _admin) { | ||
require(_admin != address(0), "Admin address cannot be zero"); | ||
admin = _admin; | ||
} | ||
|
||
modifier onlyAdmin() { | ||
require(msg.sender == admin, "Only admin can call this function"); | ||
_; | ||
} | ||
|
||
function addToWhitelist(address _address) external onlyAdmin { | ||
whitelistedAddresses[_address] = true; | ||
} | ||
|
||
function removeFromWhitelist(address _address) external onlyAdmin { | ||
whitelistedAddresses[_address] = false; | ||
} | ||
|
||
function isWhitelisted(address _address) public view returns (bool) { | ||
return whitelistedAddresses[_address]; | ||
} | ||
|
||
// Mints native tokens if the sender is whitelisted. | ||
// See: https://github.com/primevprotocol/go-ethereum/blob/precompile-updates/core/vm/contracts_with_ctx.go#L83 | ||
function mint(address _mintTo, uint256 _amount) external { | ||
require(isWhitelisted(msg.sender), "Sender is not whitelisted"); | ||
bool success; | ||
(success, ) = MINT.call{value: 0, gas: gasleft()}( | ||
abi.encode(_mintTo, _amount) | ||
); | ||
require(success, "Native mint failed"); | ||
} | ||
|
||
// Burns native tokens if the sender is whitelisted. | ||
// See: https://github.com/primevprotocol/go-ethereum/blob/precompile-updates/core/vm/contracts_with_ctx.go#L111 | ||
function burn(address _burnFrom, uint256 _amount) external { | ||
require(isWhitelisted(msg.sender), "Sender is not whitelisted"); | ||
bool success; | ||
(success, ) = BURN.call{value: 0, gas: gasleft()}( | ||
abi.encode(_burnFrom, _amount) | ||
); | ||
require(success, "Native burn failed"); | ||
} | ||
} |
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 |
---|---|---|
@@ -0,0 +1,59 @@ | ||
// SPDX-License-Identifier: BSL 1.1 | ||
pragma solidity ^0.8.20; | ||
|
||
import "forge-std/Test.sol"; | ||
import "../contracts/Whitelist.sol"; | ||
|
||
// Tests the Whitelist contract. | ||
// Note precompile interactions to mint/burn must be tested manually. | ||
contract WhitelistTest is Test { | ||
|
||
address admin; | ||
address normalUser; | ||
address addressInstance; | ||
Whitelist whitelist; | ||
|
||
function setUp() public { | ||
admin = address(this); // Original contract deployer as admin | ||
normalUser = address(0x100); | ||
addressInstance = address(0x200); | ||
whitelist = new Whitelist(admin); | ||
} | ||
|
||
function test_IsWhitelisted() public { | ||
assertFalse(whitelist.isWhitelisted(addressInstance)); | ||
vm.prank(admin); | ||
whitelist.addToWhitelist(addressInstance); | ||
assertTrue(whitelist.isWhitelisted(addressInstance)); | ||
} | ||
|
||
function test_AdminAddToWhitelist() public { | ||
vm.prank(admin); | ||
whitelist.addToWhitelist(addressInstance); | ||
assertTrue(whitelist.isWhitelisted(addressInstance)); | ||
} | ||
|
||
function test_AdminRemoveFromWhitelist() public { | ||
vm.prank(admin); | ||
whitelist.addToWhitelist(addressInstance); | ||
assertTrue(whitelist.isWhitelisted(addressInstance)); | ||
vm.prank(admin); | ||
whitelist.removeFromWhitelist(addressInstance); | ||
assertFalse(whitelist.isWhitelisted(addressInstance)); | ||
} | ||
|
||
function test_RevertNormalUserAddToWhitelist() public { | ||
vm.prank(normalUser); | ||
vm.expectRevert("Only admin can call this function"); | ||
whitelist.addToWhitelist(addressInstance); | ||
} | ||
|
||
function test_RevertNormalUserRemoveFromWhitelist() public { | ||
vm.prank(admin); | ||
whitelist.addToWhitelist(addressInstance); | ||
assertTrue(whitelist.isWhitelisted(addressInstance)); | ||
vm.prank(normalUser); | ||
vm.expectRevert("Only admin can call this function"); | ||
whitelist.removeFromWhitelist(addressInstance); | ||
} | ||
} |