Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Points contract #65

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions contracts/tokenWrappers/PointToken.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.8.7;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import { ICore } from "../interfaces/ICore.sol";
import "../utils/Errors.sol";

/// @title PointToken
/// @author Angle Labs, Inc.
/// @notice Reference contract for points systems within Merkl
contract PointToken is ERC20 {
mapping(address => bool) public minters;
mapping(address => bool) public whitelistedRecipients;
ICore public accessControlManager;
uint8 public allowedTransfers;

constructor(
string memory name_,
string memory symbol_,
address _minter,
address _accessControlManager
) ERC20(name_, symbol_) {
if (_accessControlManager == address(0) || _minter == address(0)) revert ZeroAddress();
accessControlManager = ICore(_accessControlManager);
minters[_minter] = true;
}

modifier onlyGovernorOrGuardian() {
if (!accessControlManager.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();
_;
}

modifier onlyMinter() {
if (!minters[msg.sender]) revert NotTrusted();
_;
}

function mint(address account, uint256 amount) external onlyMinter {
_mint(account, amount);
}

function burn(address account, uint256 amount) external onlyMinter {
_burn(account, amount);
}

function mintBatch(address[] memory accounts, uint256[] memory amounts) external onlyMinter {
uint256 length = accounts.length;
for (uint256 i = 0; i < length; ++i) {
_mint(accounts[i], amounts[i]);
}
}

function toggleMinter(address minter) external onlyGovernorOrGuardian {
minters[minter] = !minters[minter];
}

function toggleAllowedTransfers() external onlyGovernorOrGuardian {
allowedTransfers = 1 - allowedTransfers;
}

function toggleWhitelistedRecipient(address recipient) external onlyGovernorOrGuardian {
whitelistedRecipients[recipient] = !whitelistedRecipients[recipient];
}

function _beforeTokenTransfer(address from, address to, uint256) internal view override {
if (
allowedTransfers == 0 &&
from != address(0) &&
to != address(0) &&
!whitelistedRecipients[from] &&
!whitelistedRecipients[to]
) revert NotAllowed();
}
}
1 change: 1 addition & 0 deletions contracts/utils/Errors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ error InvalidUninitializedRoot();
error InvalidReward();
error InvalidSignature();
error NoDispute();
error NotAllowed();
error NotGovernor();
error NotGovernorOrGuardian();
error NotSigned();
Expand Down
30 changes: 30 additions & 0 deletions deploy/pointToken.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { DeployFunction } from 'hardhat-deploy/types';
import yargs from 'yargs';

const argv = yargs.env('').boolean('ci').parseSync();

const func: DeployFunction = async ({ deployments, ethers, network }) => {
const { deploy } = deployments;
const { deployer } = await ethers.getNamedSigners();
let core: string;

const implementationName = 'PointToken';

console.log(`Now deploying ${implementationName}`);
console.log('Starting with the implementation');

await deploy(implementationName, {
contract: implementationName,
from: deployer.address,
args: ["Angle Prots","agProts", "0xA9DdD91249DFdd450E81E1c56Ab60E1A62651701","0xFD0DFC837Fe7ED19B23df589b6F6Da5a775F99E0"],
log: !argv.ci,
});

const implementationAddress = (await ethers.getContract(implementationName)).address;

console.log(`Successfully deployed the contract ${implementationName} at ${implementationAddress}`);
console.log('');
};

func.tags = ['pointToken'];
export default func;
Loading
Loading