-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* forta init * wip * added high bnbx mint, high bnbx unstake * wip * rewards pct change done * startDelegation, completeDelegation delay completed * bot undelegation failures tracked * readme update * er-drop, bnbx-supply done * README pdate * minor changes * small changes * bots published * added reorg fix * fix: added blockNumber impl. * updated logs * kol initial contracts * make contract gasless * make contracts upgradeable * rename * kol not allowed as user * info json added * minor PR updates
- Loading branch information
Manoj Patra
authored
Jan 13, 2023
1 parent
0c3f1f1
commit 0d803f3
Showing
7 changed files
with
269 additions
and
0 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,139 @@ | ||
// SPDX-License-Identifier: GPL-3.0 | ||
pragma solidity ^0.8.0; | ||
|
||
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; | ||
import "@opengsn/contracts/src/ERC2771Recipient.sol"; | ||
|
||
contract KOLReferral is Initializable, ERC2771Recipient { | ||
address public admin; | ||
|
||
mapping(address => string) public walletToReferralId; | ||
mapping(string => address) public referralIdToWallet; | ||
mapping(address => string) public userReferredBy; | ||
mapping(address => address[]) private _kolToUsers; | ||
|
||
address[] private _users; | ||
address[] private _kols; | ||
|
||
modifier onlyAdmin() { | ||
require(_msgSender() == admin, "Only Admin"); | ||
_; | ||
} | ||
|
||
/// @custom:oz-upgrades-unsafe-allow constructor | ||
constructor() { | ||
_disableInitializers(); | ||
} | ||
|
||
function initialize(address admin_, address trustedForwarder_) | ||
external | ||
initializer | ||
{ | ||
require(admin_ != address(0), "zero address"); | ||
require(trustedForwarder_ != address(0), "zero address"); | ||
admin = admin_; | ||
_setTrustedForwarder(trustedForwarder_); | ||
} | ||
|
||
function registerKOL(address wallet, string memory referralId) | ||
external | ||
onlyAdmin | ||
{ | ||
require( | ||
referralIdToWallet[referralId] == address(0), | ||
"ReferralId is already taken" | ||
); | ||
require( | ||
bytes(walletToReferralId[wallet]).length == 0, | ||
"ReferralId is already assigned for this wallet" | ||
); | ||
walletToReferralId[wallet] = referralId; | ||
referralIdToWallet[referralId] = wallet; | ||
_kols.push(wallet); | ||
} | ||
|
||
function storeUserInfo(string memory referralId) external { | ||
require( | ||
referralIdToWallet[referralId] != address(0), | ||
"Invalid ReferralId" | ||
); | ||
require( | ||
bytes(userReferredBy[_msgSender()]).length == 0, | ||
"User is already referred before" | ||
); | ||
userReferredBy[_msgSender()] = referralId; | ||
_users.push(_msgSender()); | ||
|
||
address kolWallet = referralIdToWallet[referralId]; | ||
|
||
require(_msgSender() != kolWallet, "kol not allowed as user"); | ||
_kolToUsers[kolWallet].push(_msgSender()); | ||
} | ||
|
||
function queryUserReferrer(address user) | ||
external | ||
view | ||
returns (address _referrer) | ||
{ | ||
string memory referralId = userReferredBy[user]; | ||
return referralIdToWallet[referralId]; | ||
} | ||
|
||
function getKOLUserList(address kol) | ||
external | ||
view | ||
returns (address[] memory) | ||
{ | ||
return _kolToUsers[kol]; | ||
} | ||
|
||
function getKOLs() external view returns (address[] memory) { | ||
return _kols; | ||
} | ||
|
||
function getUsers(uint256 startIdx, uint256 maxNumUsers) | ||
external | ||
view | ||
returns (uint256 numUsers, address[] memory userList) | ||
{ | ||
require(startIdx < _users.length, "invalid startIdx"); | ||
|
||
if (startIdx + maxNumUsers > _users.length) { | ||
maxNumUsers = _users.length - startIdx; | ||
} | ||
|
||
userList = new address[](maxNumUsers); | ||
for ( | ||
numUsers = 0; | ||
startIdx < _users.length && numUsers < maxNumUsers; | ||
numUsers++ | ||
) { | ||
userList[numUsers] = _users[startIdx++]; | ||
} | ||
|
||
return (numUsers, userList); | ||
} | ||
|
||
function getKOLCount() external view returns (uint256) { | ||
return _kols.length; | ||
} | ||
|
||
function getUserCount() external view returns (uint256) { | ||
return _users.length; | ||
} | ||
|
||
function getKOLRefCount(address kol) external view returns (uint256) { | ||
return _kolToUsers[kol].length; | ||
} | ||
|
||
function setAdmin(address admin_) external onlyAdmin { | ||
require(admin_ != address(0), "zero address"); | ||
require(admin_ != admin, "old admin == new admin"); | ||
admin = admin_; | ||
} | ||
|
||
function setTrustedForwarder(address trustedForwarder_) external onlyAdmin { | ||
require(trustedForwarder_ != address(0), "zero address"); | ||
_setTrustedForwarder(trustedForwarder_); | ||
} | ||
} |
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,13 @@ | ||
{ | ||
"testnet": { | ||
"contract": "0x50C15cb832dcBFB9ee4b95d101608b664F06D7f7", | ||
"admin": "0x8e39FBBA48014E8a36b36dad183d2A00E9c750cC", | ||
"trustedForwarder": "0x61456BF1715C1415730076BB79ae118E806E74d2" | ||
}, | ||
"beta": { | ||
"contract": "0x3629787a59418732B388ED398928c5Bb9f4E74f1", | ||
"proxyAdmin": "0xcb507d421540f1ec1b8adcaf81995c7c89f4213e", | ||
"admin": "0x8e39FBBA48014E8a36b36dad183d2A00E9c750cC", | ||
"trustedForwarder": "0x86C80a8aa58e0A4fa09A69624c31Ab2a6CAD56b8" | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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,67 @@ | ||
import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"; | ||
import { expect } from "chai"; | ||
import { ethers, upgrades } from "hardhat"; | ||
import { KOLReferral } from "../typechain"; | ||
|
||
describe("KOL referral Contract", () => { | ||
let admin: SignerWithAddress; | ||
let kol1: SignerWithAddress; | ||
let trustedForwarder: SignerWithAddress; | ||
let users: SignerWithAddress[]; | ||
let kolContract: KOLReferral; | ||
|
||
beforeEach(async () => { | ||
[admin, kol1, trustedForwarder, ...users] = await ethers.getSigners(); | ||
|
||
kolContract = (await upgrades.deployProxy( | ||
await ethers.getContractFactory("KOLReferral"), | ||
[admin.address, trustedForwarder.address] | ||
)) as KOLReferral; | ||
await kolContract.deployed(); | ||
}); | ||
|
||
it("register a kol", async () => { | ||
let referralId1: string = "kol_1_ref_id"; | ||
|
||
expect(await kolContract.walletToReferralId(kol1.address)).be.eq(""); | ||
expect(await kolContract.referralIdToWallet(referralId1)).be.eq( | ||
ethers.constants.AddressZero | ||
); | ||
expect(await kolContract.getKOLCount()).be.eq(0); | ||
|
||
await kolContract.registerKOL(kol1.address, referralId1); | ||
expect(await kolContract.walletToReferralId(kol1.address)).be.eq( | ||
referralId1 | ||
); | ||
expect(await kolContract.referralIdToWallet(referralId1)).be.eq( | ||
kol1.address | ||
); | ||
expect(await kolContract.getKOLCount()).be.eq(1); | ||
}); | ||
|
||
it("store user info", async () => { | ||
let referralId1: string = "kol_1_ref_id"; | ||
await kolContract.registerKOL(kol1.address, referralId1); | ||
|
||
expect(await kolContract.getUserCount()).to.be.eq(0); | ||
expect(await kolContract.getKOLRefCount(kol1.address)).be.eq(0); | ||
|
||
let u1kolContract = kolContract.connect(users[0]); | ||
await u1kolContract.storeUserInfo(referralId1); | ||
|
||
expect(await kolContract.queryUserReferrer(users[0].address)).to.be.eq( | ||
kol1.address | ||
); | ||
expect(await kolContract.getKOLRefCount(kol1.address)).be.eq(1); | ||
|
||
const totalUsers = await kolContract.getUserCount(); | ||
const { numUsers, userList } = await kolContract.getUsers(0, totalUsers); | ||
expect(userList[0]).to.be.eq(users[0].address); | ||
expect(numUsers).to.be.eq(1); | ||
expect(numUsers).to.be.eq(totalUsers); | ||
|
||
await expect( | ||
kolContract.connect(kol1).storeUserInfo(referralId1) | ||
).be.revertedWith("kol not allowed as user"); | ||
}); | ||
}); |