Created
March 12, 2022 00:00
-
-
Save beauwilliams/bfcf864bc539d368e23758c6ead52261 to your computer and use it in GitHub Desktop.
A demonstraction of a claimable allocation contract for MACS
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
// SPDX-License-Identifier: MIT | |
pragma solidity >=0.7.0; | |
import "@openzeppelin/contracts/utils/math/SafeMath.sol"; | |
interface IERC20 { | |
function totalSupply() external view returns (uint256); | |
function decimals() external view returns (uint8); | |
function symbol() external view returns (string memory); | |
function name() external view returns (string memory); | |
function getOwner() external view returns (address); | |
function balanceOf(address account) external view returns (uint256); | |
function transfer(address recipient, uint256 amount) external returns (bool); | |
function allowance(address _owner, address spender) external view returns (uint256); | |
function approve(address spender, uint256 amount) external returns (bool); | |
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); | |
event Transfer(address indexed from, address indexed to, uint256 value); | |
event Approval(address indexed owner, address indexed spender, uint256 value); | |
} | |
abstract contract Auth { | |
address owner; | |
mapping (address => bool) private authorisations; | |
constructor(address _owner) { | |
owner = _owner; | |
authorisations[_owner] = true; | |
} | |
modifier onlyOwner() { | |
require(isOwner(msg.sender)); _; | |
} | |
modifier authorised() { | |
require(isAuthorised(msg.sender)); _; | |
} | |
function authorise(address adr) public onlyOwner { | |
authorisations[adr] = true; | |
emit Authorised(adr); | |
} | |
function unauthorise(address adr) public onlyOwner { | |
authorisations[adr] = false; | |
emit Unauthorised(adr); | |
} | |
function isOwner(address account) public view returns (bool) { | |
return account == owner; | |
} | |
function isAuthorised(address adr) public view returns (bool) { | |
return authorisations[adr]; | |
} | |
function transferOwnership(address newOwner) public onlyOwner { | |
address oldOwner = owner; | |
owner = newOwner; | |
authorisations[oldOwner] = false; | |
authorisations[newOwner] = true; | |
emit Unauthorised(oldOwner); | |
emit OwnershipTransferred(oldOwner, newOwner); | |
} | |
event OwnershipTransferred(address oldOwner, address newOwner); | |
event Authorised(address adr); | |
event Unauthorised(address adr); | |
} | |
contract MACSAllocation is Auth { | |
using SafeMath for uint256; | |
address public MACSTokenAddress; | |
bool public allocated; | |
mapping (address => uint256) public shares; | |
mapping (address => bool) public claimed; | |
uint256 public totalShares; | |
uint256 public totalClaimed; | |
constructor(address _MACSTokenAddress) Auth(msg.sender) { | |
MACSTokenAddress = _MACSTokenAddress; | |
allocated = false; | |
} | |
modifier allocate(){ | |
require(!allocated); | |
_; | |
allocated = true; | |
} | |
modifier canClaim(){ | |
require(allocated); _; | |
} | |
function createAllocation(address[] memory holders, uint256[] memory amounts) external authorised allocate { | |
for(uint256 i; i<holders.length; i++){ | |
shares[holders[i]] = amounts[i]; | |
totalShares += amounts[i]; | |
} | |
} | |
function getClaimableShares(address holder) public view returns (uint256) { | |
if (!allocated) return 0; | |
if (claimed[msg.sender]) return 0; | |
return shares[holder]; | |
} | |
function getPendingAmount(address holder) public view returns (uint256) { | |
if(!allocated) return 0; | |
if (claimed[msg.sender]) return 0; | |
uint256 claimableShares = getClaimableShares(holder); | |
uint256 remainingTotalShares = totalShares - totalClaimed; | |
return claimableShares * getAllocatedTokenBalance() / remainingTotalShares; | |
} | |
function claim() external canClaim { | |
uint256 amount = getPendingAmount(msg.sender); | |
if(amount > 0){ | |
uint256 claiming = getClaimableShares(msg.sender); | |
claimed[msg.sender] = true; | |
totalClaimed += claiming; | |
IERC20(MACSTokenAddress).transfer(msg.sender, amount); | |
} | |
} | |
function updateTokenAddress(address newTokenAddr) public authorised { | |
MACSTokenAddress = newTokenAddr; | |
} | |
function getAllocatedTokenBalance() public view returns (uint256) { | |
return IERC20(MACSTokenAddress).balanceOf(address(this)); | |
} | |
function withdrawTokensToBeneficiary(address beneficiary) public authorised { | |
require(IERC20(MACSTokenAddress).transfer(beneficiary, IERC20(MACSTokenAddress).balanceOf(address(this)))); | |
} | |
function withdrawTokens() external authorised { | |
require(IERC20(MACSTokenAddress).transfer(msg.sender, IERC20(MACSTokenAddress).balanceOf(address(this)))); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment