Permalink
Switch branches/tags
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
209 lines (186 sloc) 6.87 KB
pragma solidity ^0.4.24;
import "./libraries/SafeMath.sol";
/**
*This contract allows users to sign up for the DDA Cooperative Membership.
*To complete membership DDA will provide instructions to complete KYC/AML verification
*through a system external to this contract.
*/
contract Membership {
using SafeMath for uint256;
/*Variables*/
address public owner;
//Memebership fees
uint public memberFee;
/*Structs*/
/**
*@dev Keeps member information
*/
struct Member {
uint memberId;
uint membershipType;
}
/*Mappings*/
//Members information
mapping(address => Member) public members;
address[] public membersAccts;
mapping (address => uint) public membersAcctsIndex;
/*Events*/
event UpdateMemberAddress(address _from, address _to);
event NewMember(address _address, uint _memberId, uint _membershipType);
event Refund(address _address, uint _amount);
/*Modifiers*/
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
/*Functions*/
/**
*@dev Constructor - Sets owner
*/
constructor() public {
owner = msg.sender;
}
/*
*@dev Updates the fee amount
*@param _memberFee fee amount for member
*/
function setFee(uint _memberFee) public onlyOwner() {
//define fee structure for the three membership types
memberFee = _memberFee;
}
/**
*@notice Allows a user to become DDA members if they pay the fee. However, they still have to complete
*complete KYC/AML verification off line
*@dev This creates and transfers the token to the msg.sender
*/
function requestMembership() public payable {
Member storage sender = members[msg.sender];
require(msg.value >= memberFee && sender.membershipType == 0 );
membersAcctsIndex[msg.sender] = membersAccts.length;
membersAccts.push(msg.sender);
sender.memberId = membersAccts.length;
sender.membershipType = 1;
emit NewMember(msg.sender, sender.memberId, sender.membershipType);
}
/**
*@dev This updates/transfers the member address
*@param _from is the current member address
*@param _to is the address the member would like to update their current address with
*/
function updateMemberAddress(address _from, address _to) public onlyOwner {
require(_to != address(0));
Member storage currentAddress = members[_from];
Member storage newAddress = members[_to];
require(newAddress.memberId == 0);
newAddress.memberId = currentAddress.memberId;
newAddress.membershipType = currentAddress.membershipType;
membersAccts[currentAddress.memberId - 1] = _to;
currentAddress.memberId = 0;
currentAddress.membershipType = 0;
emit UpdateMemberAddress(_from, _to);
}
/**
*@dev Use this function to set membershipType for the member
*@param _memberAddress address of member that we need to update membershipType
*@param _membershipType type of membership to assign to member
*/
function setMembershipType(address _memberAddress, uint _membershipType) public onlyOwner{
Member storage memberAddress = members[_memberAddress];
memberAddress.membershipType = _membershipType;
}
/**
*@dev Use this function to set memberId for the member
*@param _memberAddress address of member that we need to update membershipType
*@param _memberId is the manually assigned memberId
*/
function setMemberId(address _memberAddress, uint _memberId) public onlyOwner{
Member storage memberAddress = members[_memberAddress];
memberAddress.memberId = _memberId;
}
/**
*@dev Use this function to remove member acct from array memberAcct
*@param _memberAddress address of member to remove
*/
function removeMemberAcct(address _memberAddress) public onlyOwner{
require(_memberAddress != address(0));
uint256 indexToDelete;
uint256 lastAcctIndex;
address lastAdd;
Member storage memberAddress = members[_memberAddress];
memberAddress.memberId = 0;
memberAddress.membershipType = 0;
indexToDelete = membersAcctsIndex[_memberAddress];
lastAcctIndex = membersAccts.length.sub(1);
lastAdd = membersAccts[lastAcctIndex];
membersAccts[indexToDelete]=lastAdd;
membersAcctsIndex[lastAdd] = indexToDelete;
membersAccts.length--;
membersAcctsIndex[_memberAddress]=0;
}
/**
*@dev Use this function to member acct from array memberAcct
*@param _memberAddress address of member to add
*/
function addMemberAcct(address _memberAddress) public onlyOwner{
require(_memberAddress != address(0));
Member storage memberAddress = members[_memberAddress];
membersAcctsIndex[_memberAddress] = membersAccts.length;
membersAccts.push(_memberAddress);
memberAddress.memberId = membersAccts.length;
memberAddress.membershipType = 1;
emit NewMember(_memberAddress, memberAddress.memberId, memberAddress.membershipType);
}
/**
*@dev getter function to get all membersAccts
*/
function getMembers() view public returns (address[]){
return membersAccts;
}
/**
*@dev Get member information
*@param _memberAddress address to pull the memberId, membershipType and membership
*/
function getMember(address _memberAddress) view public returns(uint, uint) {
return(members[_memberAddress].memberId, members[_memberAddress].membershipType);
}
/**
*@dev Gets length of array containing all member accounts or total supply
*/
function countMembers() view public returns(uint) {
return membersAccts.length;
}
/**
*@dev Gets membership type
*@param _memberAddress address to view the membershipType
*/
function getMembershipType(address _memberAddress) public constant returns(uint){
return members[_memberAddress].membershipType;
}
/**
*@dev Allows the owner to set a new owner address
*@param _new_owner the new owner address
*/
function setOwner(address _new_owner) public onlyOwner() {
owner = _new_owner;
}
/**
*@dev Refund money if KYC/AML fails
*@param _to address to send refund
*@param _amount to refund. If no amount is specified the current memberFee is refunded
*/
function refund(address _to, uint _amount) public onlyOwner {
require (_to != address(0));
if (_amount == 0) {_amount = memberFee;}
removeMemberAcct(_to);
_to.transfer(_amount);
emit Refund(_to, _amount);
}
/**
*@dev Allow owner to withdraw funds
*@param _to address to send funds
*@param _amount to send
*/
function withdraw(address _to, uint _amount) public onlyOwner {
_to.transfer(_amount);
}
}