Skip to content

Feature/refferal contract #75

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

Open
wants to merge 19 commits into
base: master
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
135 changes: 135 additions & 0 deletions contracts/Referral.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/* Copyright (C) 2020 PlotX.io

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see http://www.gnu.org/licenses/ */

pragma solidity 0.5.7;

import "./PlotXToken.sol";
import "./external/openzeppelin-solidity/math/SafeMath.sol";
import "./external/openzeppelin-solidity/token/ERC20/ERC20.sol";

interface IbLOTToken {
function mint(address account, uint256 amount) external returns (bool);
}

contract Referral {

using SafeMath for uint256;
IbLOTToken bLotToken;
PlotXToken public plotToken;
address public owner;
address public signer;
uint public endDate;
uint public remainingbudget;
uint public referralAmount;


/// @dev mapping to maintain if user have claimed or not
mapping(address => bool) public userClaimed;

/**
* @dev modifier that allows only the owner to execute the function
*/
modifier onlyOwner() {
require(owner == msg.sender, "Not owner");
_;
}

/**
* @dev Constructor
* @param _plotToken The address of plot token
* @param _bLotToken The address of BLot token
* @param _endDate user can claim thier allocated amounts before this time.
* @param _budget total amount of BLot to be minted
*/
constructor(address _plotToken, address _bLotToken, address _signer, uint _endDate, uint _budget, uint _referralAmount) public
{
require(_plotToken != address(0),"Cannot be null address");
require(_bLotToken != address(0),"Cannot be null address");
require(_signer != address(0),"Cannot be null address");
require(_referralAmount != 0,"Cannot be zero referral amount");
require(_budget >= _referralAmount,"Cannot be less than referral amount");
require(_endDate > now,"End date cannot be past time");
plotToken = PlotXToken(_plotToken);
bLotToken = IbLOTToken(_bLotToken);
owner = msg.sender;
signer = _signer;
endDate = _endDate;
remainingbudget = _budget;
referralAmount = _referralAmount;
plotToken.approve(address(bLotToken), _budget);
}

/**
* @dev Allows owner to take back left over plot token after end date.
*/
function takeLeftOverPlot() external onlyOwner {
require(endDate <= now, "Callable only after end date");
plotToken.transfer(owner, plotToken.balanceOf(address(this)));
}

/**
* @dev Allows owner to end the referral program and take back left over plot token.
*/
function endReferralCampaign() external onlyOwner {
endDate = now;
plotToken.transfer(owner, plotToken.balanceOf(address(this)));
}

/**
* @dev Allows users to claim their allocated tokens.
* user should claim before end date.
*/
function claim(uint8 v, bytes32 r, bytes32 s) external {
require(endDate > now, "Callable only before end date");
require(!userClaimed[msg.sender], "Already claimed");
bytes memory hash = abi.encode(msg.sender);
require(isValidSignature(hash, v, r, s));
userClaimed[msg.sender] = true;
bLotToken.mint(msg.sender, referralAmount);
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest adding a function to change the signer in case the signer gets compromised or something.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a function to update signer address

/**
* @dev Verifies signature.
* @param hash order hash
* @param v argument from vrs hash.
* @param r argument from vrs hash.
* @param s argument from vrs hash.
*/
function isValidSignature(bytes memory hash, uint8 v, bytes32 r, bytes32 s) public view returns(bool) {
bytes memory prefix = "\x19Ethereum Signed Message:\n32";
bytes32 prefixedHash = keccak256(abi.encodePacked(prefix, hash));
address _signer = ecrecover(prefixedHash, v, r, s);
return (_signer == signer);
}

/**
* @dev Allows owner to transfer ownership to other address.
* @param _newOwner new owner address
*/
function tranferOwnership(address _newOwner) external onlyOwner {
require(_newOwner != address(0), "Can not be null address");
owner = _newOwner;
}

/**
* @dev Allows owner to update the signer address.
* @param _newSigner new signer address
*/
function updateSigner(address _newSigner) external onlyOwner {
require(_newSigner != address(0), "Can not be null address");
signer = _newSigner;
}

}
49 changes: 49 additions & 0 deletions contracts/ReferralV2.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/* Copyright (C) 2020 PlotX.io

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see http://www.gnu.org/licenses/ */

pragma solidity 0.5.7;

import "./Referral.sol";

contract ReferralV2 is Referral {

Referral public referralV1;

/**
* @dev Constructor
* @param _plotToken The address of PLOT token
* @param _bLotToken The address of BPlot token
* @param _endDate user can claim thier allocated amounts before this time.
* @param _budget total amount of BLot to be minted
*/
constructor(address _plotToken, address _bLotToken, address _signer, uint _endDate, uint _budget, uint _referralAmount, address _referralV1Address) public
Referral(_plotToken, _bLotToken, _signer, _endDate, _budget, _referralAmount){
referralV1 = Referral(_referralV1Address);
}

/**
* @dev Allows users to claim their allocated tokens.
* user should claim before end date.
*/
function claim(uint8 v, bytes32 r, bytes32 s) external {
require(endDate > now, "Callable only before end date");
require(!userClaimed[msg.sender] && !referralV1.userClaimed(msg.sender), "Already claimed");
bytes memory hash = abi.encode(msg.sender);
require(isValidSignature(hash, v, r, s));
userClaimed[msg.sender] = true;
bLotToken.mint(msg.sender, referralAmount);
}

}
8 changes: 4 additions & 4 deletions test/01_hourlyMarketOptionPrice.js
Original file line number Diff line number Diff line change
Expand Up @@ -422,20 +422,20 @@ contract("Market", async function([user1, user2, user3, user4, user5, user6, use
//console.log("Round off ETH price of option1", optionPriceETH1 / 1000);
//console.log("Round off LOT price of option1", optionPriceLOT1 / 1000);
let optionPriceETH2 = priceOption2_af / 1;
let optionPriceLOT2 = priceOption2_af / 1 / tokenPrice;
let optionPriceLOT2 = (optionPriceETH2) * 100 / 100 / 1 / tokenPrice/ 1000;
//console.log("Round off ETH price of option2", optionPriceETH2 / 1000);
//console.log("Round off LOT price of option2", optionPriceLOT2 / 1000);
let optionPriceETH3 = priceOption3_af / 1;
let optionPriceLOT3 = priceOption3_af / 1 / tokenPrice;
let optionPriceLOT3 = (optionPriceETH3) * 100 / 100 / 1 / tokenPrice/ 1000;
//console.log("Round off ETH price of option3", optionPriceETH3 / 1000);
//console.log("Round off LOT price of option3", optionPriceLOT3 / 1000);

assert.equal(parseFloat(Math.floor((optionPriceETH1 / 1000) * 100) / 100), 0.13);
assert.equal(parseFloat(Math.floor((optionPriceETH2 / 1000) * 100) / 100), 0.15);
assert.equal(parseFloat(Math.floor((optionPriceETH3 / 1000) * 100) / 100), 0.08);
assert.equal(parseInt(optionPriceLOT1 / 1000) , parseInt(11.33));
assert.equal(parseInt(optionPriceLOT2 / 1000) , parseInt(12.5));
assert.equal(parseInt(optionPriceLOT3 / 1000) , parseInt(6.66));
assert.equal(~~(optionPriceLOT2) , parseInt(12.5));
assert.equal(~~(optionPriceLOT3) , parseInt(6.66));
});
});

Expand Down
Loading