gn-contract 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.openzeppelin/bsc-testnet.json +1847 -0
- package/.prettierrc +15 -0
- package/README.md +14 -0
- package/constants/getter.ts +4 -0
- package/constants/rootAddress.ts +22 -0
- package/contracts/CROWD.sol +32 -0
- package/contracts/CUSDT.sol +32 -0
- package/contracts/NFT.sol +499 -0
- package/contracts/NFTFounder.sol +254 -0
- package/contracts/NFTGenesis.sol +337 -0
- package/contracts/Network.sol +503 -0
- package/contracts/Swap.sol +86 -0
- package/contracts/USDT.sol +32 -0
- package/contracts/lib/AccessControl.sol +35 -0
- package/contracts/lib/NFTGetter.sol +60 -0
- package/contracts/lib/NFTHelpers.sol +111 -0
- package/contracts/lib/ValhallaBlackList.sol +18 -0
- package/contracts/lib/ValhallaPool.sol +44 -0
- package/hardhat.config.ts +44 -0
- package/package.json +50 -0
- package/scripts/DeployNetwork.ts +123 -0
- package/scripts/DeploySwap.ts +57 -0
- package/scripts/DeployUSDT.ts +16 -0
- package/test/Swap.test.ts +182 -0
- package/test/lib/initializer.ts +193 -0
- package/test/nft_genesis.test.ts +399 -0
- package/test/nft_purchase.test.ts +210 -0
- package/test/rank_distribution.test.ts +142 -0
- package/test/registration.test.ts +267 -0
- package/test/registration_reward.test.ts +114 -0
- package/tsconfig.json +11 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { expect } from "chai";
|
|
2
|
+
import { fromBn, toBn } from "evm-bn";
|
|
3
|
+
import { ethers } from "hardhat";
|
|
4
|
+
import { initialize, getState, getAccounts } from "./lib/initializer";
|
|
5
|
+
import { reserveAddress } from "../constants/rootAddress";
|
|
6
|
+
import { BigNumber } from "ethers";
|
|
7
|
+
|
|
8
|
+
describe("Valhalla Rank Distribution", function () {
|
|
9
|
+
before(async () => {
|
|
10
|
+
await initialize();
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it("parent should become Rank Common", async () => {
|
|
14
|
+
const { valhalla, usdt } = getState();
|
|
15
|
+
const accounts = await getAccounts(14, 101);
|
|
16
|
+
const owner = await getAccounts(0);
|
|
17
|
+
|
|
18
|
+
const parent = accounts[0];
|
|
19
|
+
for (let i = 1; i <= 100; i++) {
|
|
20
|
+
const tranferErc20 = await usdt
|
|
21
|
+
.connect(owner[0])
|
|
22
|
+
.transfer(accounts[i].address, toBn("60", 18));
|
|
23
|
+
await tranferErc20.wait();
|
|
24
|
+
|
|
25
|
+
const userApprove = await usdt
|
|
26
|
+
.connect(accounts[i])
|
|
27
|
+
.approve(valhalla.address, await usdt.balanceOf(accounts[i].address));
|
|
28
|
+
await userApprove.wait();
|
|
29
|
+
|
|
30
|
+
const account = accounts[i];
|
|
31
|
+
const tx = await valhalla.connect(account).register(parent.address);
|
|
32
|
+
const receipt = await tx.wait();
|
|
33
|
+
expect(receipt.status).to.eq(1);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const parentAccount = await valhalla.accountMap(parent.address);
|
|
37
|
+
expect(parentAccount.rank).to.eq(1);
|
|
38
|
+
expect(parentAccount.downlineCount).to.eq(100);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("should bump rank distribution count", async () => {
|
|
42
|
+
const { valhalla } = getState();
|
|
43
|
+
const { common } = await valhalla.rankDistribution();
|
|
44
|
+
expect(common.toString()).to.eq(String(15));
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("should have correct ipo pool value", async () => {
|
|
48
|
+
const { valhalla } = getState();
|
|
49
|
+
const ipoPool = await valhalla.getIpoPool();
|
|
50
|
+
expect(ipoPool.claimable).to.eq(0);
|
|
51
|
+
expect(ipoPool.valueLeft).to.eq(0);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("should have correct global pool value", async () => {
|
|
55
|
+
const { valhalla } = getState();
|
|
56
|
+
const globalPoolVal = await valhalla.getGlobalPool();
|
|
57
|
+
const valPerRegistration = toBn("50", 18).mul(17).div(100);
|
|
58
|
+
expect(globalPoolVal.claimable).to.eq(valPerRegistration.mul(100));
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it("should have correct reserved balance", async () => {
|
|
62
|
+
const { usdt, nftFounder } = getState();
|
|
63
|
+
const balance = await usdt.balanceOf(nftFounder.address);
|
|
64
|
+
const valPerRegistration = toBn("50", 18).mul(3).div(100);
|
|
65
|
+
expect(balance).to.eq(valPerRegistration.mul(100));
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it("should have correct fee receiver reward", async () => {
|
|
69
|
+
const { feeReceiver, feeReceiver2, usdt } = getState();
|
|
70
|
+
const rewardFee1 = await usdt.balanceOf(feeReceiver.address);
|
|
71
|
+
const rewardFee2 = await usdt.balanceOf(feeReceiver2.address);
|
|
72
|
+
// new plan fee receiver split with two person
|
|
73
|
+
const valPerRegistration = toBn("50", 18).mul(25).div(100);
|
|
74
|
+
expect(rewardFee1).to.eq(valPerRegistration.mul(100).div(2));
|
|
75
|
+
expect(rewardFee2).to.eq(valPerRegistration.mul(100).div(2));
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it("make sure able to purchase nft", async () => {
|
|
79
|
+
const { nft, crowd } = getState();
|
|
80
|
+
const [admin] = await getAccounts(0);
|
|
81
|
+
const approveTx = await crowd
|
|
82
|
+
.connect(admin)
|
|
83
|
+
.approve(nft.address, toBn("50000", 18));
|
|
84
|
+
await approveTx.wait();
|
|
85
|
+
const tx = await nft.connect(admin).buy(1);
|
|
86
|
+
const receipt = await tx.wait();
|
|
87
|
+
expect(receipt.status).to.eq(1);
|
|
88
|
+
const tx1 = await nft.connect(admin).buy(1);
|
|
89
|
+
const receipt1 = await tx1.wait();
|
|
90
|
+
expect(receipt1.status).to.eq(1);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it("should have correct rank reward", async () => {
|
|
94
|
+
const { valhalla } = getState();
|
|
95
|
+
const [admin] = await getAccounts(0);
|
|
96
|
+
const tx = await valhalla.connect(admin).startClaimingRankReward();
|
|
97
|
+
await tx.wait();
|
|
98
|
+
const myReward = await valhalla
|
|
99
|
+
.connect(admin)
|
|
100
|
+
.getMyRankReward(admin.address);
|
|
101
|
+
const globalPool = await valhalla.getGlobalPool();
|
|
102
|
+
const { common } = await valhalla.rankDistribution();
|
|
103
|
+
const baseReward = globalPool.valueLeft.mul(3).div(100);
|
|
104
|
+
const expectedReward = baseReward.div(common);
|
|
105
|
+
expect(myReward).to.eq(expectedReward);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it("should have correct NFT rank reward", async () => {
|
|
109
|
+
const { nft, valhalla } = getState();
|
|
110
|
+
const [admin] = await getAccounts(0);
|
|
111
|
+
const myReward = await nft.getMyRankReward(admin.address);
|
|
112
|
+
const globalPool = await nft.getGlobalPool();
|
|
113
|
+
const { common } = await valhalla.rankDistribution();
|
|
114
|
+
const baseReward = globalPool.valueLeft.mul(3).div(100);
|
|
115
|
+
const expectedReward = baseReward.div(common);
|
|
116
|
+
expect(myReward).to.eq(expectedReward);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it("should be able to claim rank reward", async () => {
|
|
120
|
+
const { valhalla } = getState();
|
|
121
|
+
const [admin] = await getAccounts(0);
|
|
122
|
+
const myReward = await valhalla
|
|
123
|
+
.connect(admin)
|
|
124
|
+
.getMyRankReward(admin.address);
|
|
125
|
+
|
|
126
|
+
const { valueLeft: initialValueLeft } = await valhalla.getGlobalPool();
|
|
127
|
+
|
|
128
|
+
const tx = await valhalla.connect(admin).claimRankReward();
|
|
129
|
+
const receipt = await tx.wait();
|
|
130
|
+
expect(receipt.status).to.eq(1);
|
|
131
|
+
|
|
132
|
+
const { valueLeft } = await valhalla.getGlobalPool();
|
|
133
|
+
expect(valueLeft).to.eq(initialValueLeft.sub(myReward));
|
|
134
|
+
|
|
135
|
+
const tx2 = await valhalla.connect(admin).stopClaimingRankReward();
|
|
136
|
+
await tx2.wait();
|
|
137
|
+
|
|
138
|
+
const poolAfterStop = await valhalla.getGlobalPool();
|
|
139
|
+
expect(poolAfterStop.valueLeft).to.eq(BigNumber.from("0"));
|
|
140
|
+
expect(poolAfterStop.claimable).to.eq(initialValueLeft.sub(myReward));
|
|
141
|
+
});
|
|
142
|
+
});
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import { expect } from "chai";
|
|
2
|
+
import { toBn } from "evm-bn";
|
|
3
|
+
import { ethers } from "hardhat";
|
|
4
|
+
import { initialize, getState, getAccounts } from "./lib/initializer";
|
|
5
|
+
|
|
6
|
+
describe("Valhalla Registration", function () {
|
|
7
|
+
before(async () => {
|
|
8
|
+
await initialize();
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it("check root addresses", async () => {
|
|
12
|
+
const { valhalla } = getState();
|
|
13
|
+
let referrer = "0x0000000000000000000000000000000000000000";
|
|
14
|
+
const accounts = await getAccounts(0, 15);
|
|
15
|
+
for (let i = 0; i < 15; i++) {
|
|
16
|
+
const account = await valhalla.accountMap(accounts[i].address);
|
|
17
|
+
expect(account.referrer).to.eq(referrer);
|
|
18
|
+
expect(account.downlineCount).to.eq(15 - i - 1);
|
|
19
|
+
referrer = accounts[i].address;
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("make sure can register successfully", async () => {
|
|
24
|
+
const { valhalla, usdt } = getState();
|
|
25
|
+
const owner = await getAccounts(0);
|
|
26
|
+
const accounts = await getAccounts(14, 2);
|
|
27
|
+
const account = accounts[1];
|
|
28
|
+
|
|
29
|
+
// before registration user need USDT (20 registration fee)
|
|
30
|
+
// then user with transferred USDT need to approve their token
|
|
31
|
+
|
|
32
|
+
const transferUsdt = await usdt
|
|
33
|
+
.connect(owner[0])
|
|
34
|
+
.transfer(account.address, toBn("21", 18));
|
|
35
|
+
await transferUsdt.wait();
|
|
36
|
+
|
|
37
|
+
const approvalUsdt = await usdt
|
|
38
|
+
.connect(account)
|
|
39
|
+
.approve(valhalla.address, usdt.balanceOf(account.address));
|
|
40
|
+
await approvalUsdt.wait();
|
|
41
|
+
|
|
42
|
+
const tx = await valhalla.connect(account).register(accounts[0].address);
|
|
43
|
+
const receipt = await tx.wait();
|
|
44
|
+
expect(receipt.status).to.eq(1);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("make sure can't register if the price are below", async () => {
|
|
48
|
+
const { valhalla, usdt } = getState();
|
|
49
|
+
const owner = await getAccounts(0);
|
|
50
|
+
const accounts = await getAccounts(15, 2);
|
|
51
|
+
const account = accounts[1];
|
|
52
|
+
|
|
53
|
+
const transferUsdt = await usdt
|
|
54
|
+
.connect(owner[0])
|
|
55
|
+
.transfer(account.address, toBn("10", 18));
|
|
56
|
+
await transferUsdt.wait();
|
|
57
|
+
|
|
58
|
+
const approvalUsdt = await usdt
|
|
59
|
+
.connect(account)
|
|
60
|
+
.approve(valhalla.address, usdt.balanceOf(account.address));
|
|
61
|
+
await approvalUsdt.wait();
|
|
62
|
+
|
|
63
|
+
const tx = valhalla.connect(account).register(accounts[0].address);
|
|
64
|
+
await expect(tx).to.be.revertedWith("Unmatch Registration Fee");
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it("make sure can't register if the address already registered", async () => {
|
|
68
|
+
const { valhalla, usdt } = getState();
|
|
69
|
+
const owner = await getAccounts(0);
|
|
70
|
+
const accounts = await getAccounts(14, 2);
|
|
71
|
+
const account = accounts[1];
|
|
72
|
+
|
|
73
|
+
const transferUsdt = await usdt
|
|
74
|
+
.connect(owner[0])
|
|
75
|
+
.transfer(account.address, toBn("20", 18));
|
|
76
|
+
await transferUsdt.wait();
|
|
77
|
+
|
|
78
|
+
const approvalUsdt = await usdt
|
|
79
|
+
.connect(account)
|
|
80
|
+
.approve(valhalla.address, usdt.balanceOf(account.address));
|
|
81
|
+
await approvalUsdt.wait();
|
|
82
|
+
|
|
83
|
+
const tx = valhalla.connect(account).register(accounts[0].address);
|
|
84
|
+
await expect(tx).to.be.revertedWith("Address already registered");
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it("make sure can't register if the using zero referrer", async () => {
|
|
88
|
+
const { valhalla, usdt } = getState();
|
|
89
|
+
const owner = await getAccounts(0);
|
|
90
|
+
const accounts = await getAccounts(16);
|
|
91
|
+
const account = accounts[0];
|
|
92
|
+
|
|
93
|
+
const transferUsdt = await usdt
|
|
94
|
+
.connect(owner[0])
|
|
95
|
+
.transfer(account.address, toBn("20", 18));
|
|
96
|
+
await transferUsdt.wait();
|
|
97
|
+
|
|
98
|
+
const approvalUsdt = await usdt
|
|
99
|
+
.connect(account)
|
|
100
|
+
.approve(valhalla.address, usdt.balanceOf(account.address));
|
|
101
|
+
await approvalUsdt.wait();
|
|
102
|
+
|
|
103
|
+
const tx = valhalla
|
|
104
|
+
.connect(account)
|
|
105
|
+
.register("0x0000000000000000000000000000000000000000");
|
|
106
|
+
await expect(tx).to.be.revertedWith("Invalid referrer");
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it("make sure can't register referrer isn't registered", async () => {
|
|
110
|
+
const { valhalla, usdt } = getState();
|
|
111
|
+
const owner = await getAccounts(0);
|
|
112
|
+
const accounts = await getAccounts(16, 4);
|
|
113
|
+
const account = accounts[0];
|
|
114
|
+
|
|
115
|
+
const transferUsdt = await usdt
|
|
116
|
+
.connect(owner[0])
|
|
117
|
+
.transfer(account.address, toBn("20", 18));
|
|
118
|
+
await transferUsdt.wait();
|
|
119
|
+
|
|
120
|
+
const approvalUsdt = await usdt
|
|
121
|
+
.connect(account)
|
|
122
|
+
.approve(valhalla.address, usdt.balanceOf(account.address));
|
|
123
|
+
await approvalUsdt.wait();
|
|
124
|
+
|
|
125
|
+
const tx = valhalla.connect(account).register(accounts[3].address);
|
|
126
|
+
await expect(tx).to.be.revertedWith("Referrer should be registered");
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it("owner change, register fee", async () => {
|
|
130
|
+
const { valhalla } = getState();
|
|
131
|
+
const accounts = await getAccounts(0, 1);
|
|
132
|
+
const owner = accounts[0];
|
|
133
|
+
|
|
134
|
+
const changeFeeReg = await valhalla
|
|
135
|
+
.connect(owner)
|
|
136
|
+
.changeFeeRegister(0, toBn("15", 18));
|
|
137
|
+
|
|
138
|
+
const receipts = await changeFeeReg.wait();
|
|
139
|
+
|
|
140
|
+
expect(1).to.eq(receipts.status);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it("get registration fee", async () => {
|
|
144
|
+
const { valhalla } = getState();
|
|
145
|
+
const getRegFee = await valhalla.getRegistrationFee();
|
|
146
|
+
const expectFee = toBn("15", 18);
|
|
147
|
+
expect(expectFee).to.eq(getRegFee);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it("make sure fee register has been changed", async () => {
|
|
151
|
+
const { valhalla, usdt } = getState();
|
|
152
|
+
const _accounts = await getAccounts(0, 15);
|
|
153
|
+
|
|
154
|
+
const accounts = await getAccounts(20, 1);
|
|
155
|
+
const commonUser = accounts[0];
|
|
156
|
+
const feeRegister = toBn("15", 18);
|
|
157
|
+
|
|
158
|
+
const transferUsdt = await usdt
|
|
159
|
+
.connect(_accounts[0])
|
|
160
|
+
.transfer(commonUser.address, toBn("15", 18));
|
|
161
|
+
await transferUsdt.wait();
|
|
162
|
+
|
|
163
|
+
const approvalUsdt = await usdt
|
|
164
|
+
.connect(commonUser)
|
|
165
|
+
.approve(valhalla.address, usdt.balanceOf(commonUser.address));
|
|
166
|
+
await approvalUsdt.wait();
|
|
167
|
+
|
|
168
|
+
const balanceBefore = await usdt.balanceOf(commonUser.address);
|
|
169
|
+
|
|
170
|
+
const register = await valhalla
|
|
171
|
+
.connect(commonUser)
|
|
172
|
+
.register(_accounts[14].address);
|
|
173
|
+
|
|
174
|
+
const receipts = await register.wait();
|
|
175
|
+
expect(1).to.eq(receipts.status);
|
|
176
|
+
|
|
177
|
+
const balanceAfter = await usdt.balanceOf(commonUser.address);
|
|
178
|
+
const compare = balanceBefore.sub(balanceAfter).gte(feeRegister);
|
|
179
|
+
expect(true).to.eq(compare);
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it("make sure can't register if referrer is blacklisted", async () => {
|
|
183
|
+
const { valhalla, usdt } = getState();
|
|
184
|
+
const owner = await getAccounts(0);
|
|
185
|
+
const accounts = await getAccounts(21, 2);
|
|
186
|
+
const account = accounts[0];
|
|
187
|
+
const referrerAccount = accounts[1];
|
|
188
|
+
|
|
189
|
+
// Register the referrer first
|
|
190
|
+
const transferToReferrer = await usdt
|
|
191
|
+
.connect(owner[0])
|
|
192
|
+
.transfer(referrerAccount.address, toBn("20", 18));
|
|
193
|
+
await transferToReferrer.wait();
|
|
194
|
+
|
|
195
|
+
const approvalReferrer = await usdt
|
|
196
|
+
.connect(referrerAccount)
|
|
197
|
+
.approve(valhalla.address, usdt.balanceOf(referrerAccount.address));
|
|
198
|
+
await approvalReferrer.wait();
|
|
199
|
+
|
|
200
|
+
await valhalla.connect(referrerAccount).register(owner[0].address);
|
|
201
|
+
|
|
202
|
+
// Blacklist the referrer
|
|
203
|
+
await valhalla.connect(owner[0]).blackListAddress(referrerAccount.address);
|
|
204
|
+
|
|
205
|
+
// Try to register with blacklisted referrer
|
|
206
|
+
const transferUsdt = await usdt
|
|
207
|
+
.connect(owner[0])
|
|
208
|
+
.transfer(account.address, toBn("20", 18));
|
|
209
|
+
await transferUsdt.wait();
|
|
210
|
+
|
|
211
|
+
const approvalUsdt = await usdt
|
|
212
|
+
.connect(account)
|
|
213
|
+
.approve(valhalla.address, usdt.balanceOf(account.address));
|
|
214
|
+
await approvalUsdt.wait();
|
|
215
|
+
|
|
216
|
+
const tx = valhalla.connect(account).register(referrerAccount.address);
|
|
217
|
+
await expect(tx).to.be.revertedWith("Referrer blacklisted");
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
it("make sure can't register if registrant is blacklisted", async () => {
|
|
221
|
+
const { valhalla, usdt } = getState();
|
|
222
|
+
const owner = await getAccounts(0);
|
|
223
|
+
const accounts = await getAccounts(22, 2);
|
|
224
|
+
const account = accounts[0];
|
|
225
|
+
|
|
226
|
+
// Blacklist the registrant
|
|
227
|
+
await valhalla.connect(owner[0]).blackListAddress(account.address);
|
|
228
|
+
|
|
229
|
+
// Try to register
|
|
230
|
+
const transferUsdt = await usdt
|
|
231
|
+
.connect(owner[0])
|
|
232
|
+
.transfer(account.address, toBn("20", 18));
|
|
233
|
+
await transferUsdt.wait();
|
|
234
|
+
|
|
235
|
+
const approvalUsdt = await usdt
|
|
236
|
+
.connect(account)
|
|
237
|
+
.approve(valhalla.address, usdt.balanceOf(account.address));
|
|
238
|
+
await approvalUsdt.wait();
|
|
239
|
+
|
|
240
|
+
const tx = valhalla.connect(account).register(owner[0].address);
|
|
241
|
+
await expect(tx).to.be.revertedWith("Address blacklisted");
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
it("make sure can't register when registration is closed", async () => {
|
|
245
|
+
const { valhalla, usdt } = getState();
|
|
246
|
+
const owner = await getAccounts(0);
|
|
247
|
+
const accounts = await getAccounts(23, 1);
|
|
248
|
+
const account = accounts[0];
|
|
249
|
+
|
|
250
|
+
// Close registration by starting rank reward claiming
|
|
251
|
+
await valhalla.connect(owner[0]).startClaimingRankReward();
|
|
252
|
+
|
|
253
|
+
// Try to register
|
|
254
|
+
const transferUsdt = await usdt
|
|
255
|
+
.connect(owner[0])
|
|
256
|
+
.transfer(account.address, toBn("20", 18));
|
|
257
|
+
await transferUsdt.wait();
|
|
258
|
+
|
|
259
|
+
const approvalUsdt = await usdt
|
|
260
|
+
.connect(account)
|
|
261
|
+
.approve(valhalla.address, usdt.balanceOf(account.address));
|
|
262
|
+
await approvalUsdt.wait();
|
|
263
|
+
|
|
264
|
+
const tx = valhalla.connect(account).register(owner[0].address);
|
|
265
|
+
await expect(tx).to.be.revertedWith("Registration closed");
|
|
266
|
+
});
|
|
267
|
+
});
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { expect } from "chai";
|
|
2
|
+
import { fromBn, toBn } from "evm-bn";
|
|
3
|
+
import {
|
|
4
|
+
initialize,
|
|
5
|
+
getState,
|
|
6
|
+
getAccounts,
|
|
7
|
+
setBalance,
|
|
8
|
+
} from "./lib/initializer";
|
|
9
|
+
|
|
10
|
+
const calculateReward = (
|
|
11
|
+
refNumber: number,
|
|
12
|
+
percentage: number,
|
|
13
|
+
multiplier: number,
|
|
14
|
+
decimals?: number,
|
|
15
|
+
) => {
|
|
16
|
+
const rewardPerTransaction = toBn("" + refNumber, decimals ?? 18)
|
|
17
|
+
.mul(percentage)
|
|
18
|
+
.div(100);
|
|
19
|
+
return rewardPerTransaction.mul(multiplier);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
describe("Valhalla Registration Reward", function () {
|
|
23
|
+
before(async () => {
|
|
24
|
+
await initialize();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it("should distribute reward correctly", async () => {
|
|
28
|
+
const { valhalla, usdt, feeReceiver, feeReceiver2 } = getState();
|
|
29
|
+
const accounts = await getAccounts(15, 10);
|
|
30
|
+
const rootAccountList = await getAccounts(0, 15);
|
|
31
|
+
const usdtDecimal = await usdt.decimals();
|
|
32
|
+
|
|
33
|
+
// cleanup the root account balance
|
|
34
|
+
for (let i = 0; i < rootAccountList.length; i++) {
|
|
35
|
+
await setBalance(rootAccountList[i].address, 10);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const parent = rootAccountList[14];
|
|
39
|
+
for (let i = 0; i < accounts.length; i++) {
|
|
40
|
+
// transfer erc20 (USDT) to user
|
|
41
|
+
const transferERC20 = await usdt
|
|
42
|
+
.connect(rootAccountList[0])
|
|
43
|
+
.transfer(accounts[i].address, toBn("100", 18));
|
|
44
|
+
await transferERC20.wait();
|
|
45
|
+
|
|
46
|
+
// users need approve their token
|
|
47
|
+
const approveToken = await usdt
|
|
48
|
+
.connect(accounts[i])
|
|
49
|
+
.approve(valhalla.address, usdt.balanceOf(accounts[i].address));
|
|
50
|
+
await approveToken.wait();
|
|
51
|
+
|
|
52
|
+
const account = accounts[i];
|
|
53
|
+
const tx = await valhalla.connect(account).register(parent.address);
|
|
54
|
+
const receipt = await tx.wait();
|
|
55
|
+
expect(receipt.status).to.eq(1);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const calculationv2 = [
|
|
59
|
+
30, 8, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
60
|
+
].reverse();
|
|
61
|
+
|
|
62
|
+
for (let i = 0; i < rootAccountList.length; i++) {
|
|
63
|
+
const rewardCalculation = calculateReward(
|
|
64
|
+
50, // this value depend on refererrer pool distribution
|
|
65
|
+
calculationv2[i], // this value is list from share point from 1 - 15
|
|
66
|
+
accounts.length, // this value is list user downline
|
|
67
|
+
usdtDecimal, // this is decimal currency by default is 18
|
|
68
|
+
);
|
|
69
|
+
const rewardReal = await valhalla.rewardMap(rootAccountList[i].address);
|
|
70
|
+
expect(rewardCalculation).to.eq(rewardReal);
|
|
71
|
+
|
|
72
|
+
// reward should decrease by tax at 10%
|
|
73
|
+
const taxCalculation = rewardCalculation.mul(10).div(100);
|
|
74
|
+
const taxReal = rewardReal.mul(10).div(100);
|
|
75
|
+
const halfTax = taxReal.div(2);
|
|
76
|
+
expect(taxCalculation).to.eq(taxReal);
|
|
77
|
+
|
|
78
|
+
// the referre should be get reward sub by tax
|
|
79
|
+
const rewardGet = rewardCalculation.sub(taxCalculation);
|
|
80
|
+
|
|
81
|
+
// before claim check the ERC20 balance
|
|
82
|
+
const balanceBefore = await usdt.balanceOf(rootAccountList[i].address);
|
|
83
|
+
const balanceFeeRecieverBefore = await usdt.balanceOf(
|
|
84
|
+
feeReceiver.address,
|
|
85
|
+
);
|
|
86
|
+
const balanceFeeReciever2Before = await usdt.balanceOf(
|
|
87
|
+
feeReceiver2.address,
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
// claim reward
|
|
91
|
+
const tx = await valhalla.connect(rootAccountList[i]).claimReward();
|
|
92
|
+
await tx.wait();
|
|
93
|
+
|
|
94
|
+
// check balance after claim
|
|
95
|
+
const balanceAfter = await usdt.balanceOf(rootAccountList[i].address);
|
|
96
|
+
const balanceFeeRecieverAfter = await usdt.balanceOf(feeReceiver.address);
|
|
97
|
+
const balanceFeeReciever2After = await usdt.balanceOf(
|
|
98
|
+
feeReceiver2.address,
|
|
99
|
+
);
|
|
100
|
+
// referrer get
|
|
101
|
+
const referrerGet = balanceAfter.sub(balanceBefore);
|
|
102
|
+
expect(rewardGet).to.eq(referrerGet);
|
|
103
|
+
// fee reciever get
|
|
104
|
+
const feeReceiverGet = balanceFeeRecieverAfter.sub(
|
|
105
|
+
balanceFeeRecieverBefore,
|
|
106
|
+
);
|
|
107
|
+
const feeReceiver2Get = balanceFeeReciever2After.sub(
|
|
108
|
+
balanceFeeReciever2Before,
|
|
109
|
+
);
|
|
110
|
+
expect(feeReceiverGet).eq(halfTax);
|
|
111
|
+
expect(feeReceiver2Get).eq(halfTax);
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
});
|