@gooddollar/goodprotocol 2.1.0 → 2.1.2
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/README.md +12 -0
- package/artifacts/abis/AdminWallet.min.json +1 -1
- package/artifacts/abis/AdminWalletFuse.min.json +1 -1
- package/artifacts/abis/GenericDistributionHelperTest.min.json +1 -0
- package/artifacts/abis/GenericDistributionHelperTestHelper.min.json +1 -0
- package/artifacts/abis/IBancorExchangeProvider.min.json +1 -1
- package/artifacts/abis/IUniswapV3Pool.min.json +1 -1
- package/artifacts/abis/IdentityV3.min.json +1 -1
- package/artifacts/abis/MentoExchange.min.json +1 -1
- package/artifacts/abis/UpdateReserveRatioAfterXDC.min.json +1 -0
- package/artifacts/contracts/IUniswapV3.sol/INonfungiblePositionManager.dbg.json +1 -1
- package/artifacts/contracts/IUniswapV3.sol/IUniswapV3Pool.dbg.json +1 -1
- package/artifacts/contracts/IUniswapV3.sol/IUniswapV3Pool.json +13 -0
- package/artifacts/contracts/MentoInterfaces.sol/IBancorExchangeProvider.dbg.json +1 -1
- package/artifacts/contracts/MentoInterfaces.sol/IBancorExchangeProvider.json +13 -0
- package/artifacts/contracts/MentoInterfaces.sol/IBroker.dbg.json +1 -1
- package/artifacts/contracts/MentoInterfaces.sol/IGoodDollarExchangeProvider.dbg.json +1 -1
- package/artifacts/contracts/MentoInterfaces.sol/IGoodDollarExpansionController.dbg.json +1 -1
- package/artifacts/contracts/MentoInterfaces.sol/IMentoReserve.dbg.json +1 -1
- package/artifacts/contracts/MentoInterfaces.sol/ITradingLimits.dbg.json +1 -1
- package/artifacts/contracts/identity/IdentityV3.sol/IdentityV3.dbg.json +1 -1
- package/artifacts/contracts/identity/IdentityV3.sol/IdentityV3.json +40 -2
- package/artifacts/contracts/mocks/GenericDistributionHelperTest.sol/GenericDistributionHelperTest.dbg.json +4 -0
- package/artifacts/contracts/mocks/GenericDistributionHelperTest.sol/GenericDistributionHelperTest.json +931 -0
- package/artifacts/contracts/mocks/GenericDistributionHelperTest.sol/GenericDistributionHelperTestHelper.dbg.json +4 -0
- package/artifacts/contracts/mocks/GenericDistributionHelperTest.sol/GenericDistributionHelperTestHelper.json +957 -0
- package/artifacts/contracts/reserve/GenericDistributionHelper.sol/GenericDistributionHelper.dbg.json +1 -1
- package/artifacts/contracts/reserve/GenericDistributionHelper.sol/GenericDistributionHelper.json +2 -2
- package/artifacts/contracts/utils/AdminWallet.sol/AdminWallet.dbg.json +1 -1
- package/artifacts/contracts/utils/AdminWallet.sol/AdminWallet.json +36 -2
- package/artifacts/contracts/utils/AdminWalletFuse.sol/AdminWalletFuse.dbg.json +1 -1
- package/artifacts/contracts/utils/AdminWalletFuse.sol/AdminWalletFuse.json +36 -2
- package/artifacts/contracts/utils/BulkWhitelist.sol/BulkWhitelist.dbg.json +1 -1
- package/artifacts/contracts/utils/BulkWhitelist.sol/BulkWhitelist.json +2 -2
- package/artifacts/contracts/utils/BuyFromReserveHelper.sol/BuyFromReserveHelper.dbg.json +1 -1
- package/artifacts/contracts/utils/BuyFromReserveHelper.sol/BuyFromReserveHelper.json +2 -2
- package/artifacts/contracts/utils/BuyGDClone.sol/BuyGDClone.dbg.json +1 -1
- package/artifacts/contracts/utils/BuyGDClone.sol/BuyGDCloneFactory.dbg.json +1 -1
- package/artifacts/contracts/utils/BuyGDClone.sol/DonateGDClone.dbg.json +1 -1
- package/artifacts/contracts/utils/ProtoclUpgradeV4Mento.sol/MentoExchange.dbg.json +1 -1
- package/artifacts/contracts/utils/ProtoclUpgradeV4Mento.sol/ProtocolUpgradeV4Mento.dbg.json +1 -1
- package/artifacts/contracts/utils/ProtoclUpgradeV4Mento.sol/ProtocolUpgradeV4Mento.json +2 -2
- package/artifacts/contracts/utils/UpdateReserveRatioAfterXDC.sol/MentoExchange.dbg.json +4 -0
- package/artifacts/contracts/utils/UpdateReserveRatioAfterXDC.sol/MentoExchange.json +24 -0
- package/artifacts/contracts/utils/UpdateReserveRatioAfterXDC.sol/UpdateReserveRatioAfterXDC.dbg.json +4 -0
- package/artifacts/contracts/utils/UpdateReserveRatioAfterXDC.sol/UpdateReserveRatioAfterXDC.json +50 -0
- package/contracts/IUniswapV3.sol +2 -0
- package/contracts/identity/IdentityV3.sol +2 -0
- package/contracts/mocks/GenericDistributionHelperTest.sol +31 -0
- package/contracts/reserve/GenericDistributionHelper.sol +43 -21
- package/contracts/utils/AdminWallet.sol +27 -0
- package/contracts/utils/AdminWalletFuse.sol +27 -0
- package/contracts/utils/UpdateReserveRatioAfterXDC.sol +64 -0
- package/hardhat.config.ts +9 -12
- package/package.json +3 -2
- package/releases/deployment.json +4 -1
- package/scripts/bulkWhitelist.ts +31 -0
- package/scripts/multichain-deploy/helpers.ts +13 -6
- package/scripts/proposals/gip-25-xdc-deploy-reserve.ts +425 -0
- package/scripts/proposals/gip-25-xdc-upgrade-ubi.ts +334 -31
- package/test/governance/ClaimersDistribution.test.ts +1 -1
- package/test/reserve/GenericDistributionHelper.test.ts +315 -0
- package/test/ubi/UBISchemeCycle.test.ts +30 -63
- package/types/contracts/IUniswapV3.sol/IUniswapV3Pool.ts +14 -1
- package/types/contracts/MentoInterfaces.sol/IBancorExchangeProvider.ts +14 -0
- package/types/contracts/fuseFaucet/Faucet copy.sol/DebugFaucet.ts +1439 -0
- package/types/contracts/fuseFaucet/Faucet copy.sol/index.ts +4 -0
- package/types/contracts/identity/IdentityV3.ts +46 -0
- package/types/contracts/index.ts +0 -2
- package/types/contracts/mocks/GenericDistributionHelperTest.sol/CeloDistributionHelperTestHelper.ts +1357 -0
- package/types/contracts/mocks/GenericDistributionHelperTest.sol/GenericDistributionHelperTest.ts +1305 -0
- package/types/contracts/mocks/GenericDistributionHelperTest.sol/GenericDistributionHelperTestHelper.ts +1357 -0
- package/types/contracts/mocks/GenericDistributionHelperTest.sol/index.ts +5 -0
- package/types/contracts/mocks/index.ts +2 -0
- package/types/contracts/utils/AdminWallet.ts +45 -0
- package/types/contracts/utils/AdminWalletFuse.ts +45 -0
- package/types/contracts/utils/BuyGDClone.sol/BuyGDCloneV2.ts +464 -0
- package/types/contracts/utils/UpdateReserveRatioAfterXDC.sol/MentoExchange.ts +81 -0
- package/types/contracts/utils/UpdateReserveRatioAfterXDC.sol/UpdateReserveRatioAfterXDC.ts +117 -0
- package/types/contracts/utils/UpdateReserveRatioAfterXDC.sol/index.ts +5 -0
- package/types/contracts/utils/UpdateReserveSettingsForXdc.sol/MentoExchange.ts +81 -0
- package/types/contracts/utils/UpdateReserveSettingsForXdc.sol/UpdateReserveRatioAfterXDC.ts +122 -0
- package/types/contracts/utils/UpdateReserveSettingsForXdc.sol/index.ts +5 -0
- package/types/contracts/utils/index.ts +4 -0
- package/types/factories/contracts/IUniswapV3.sol/IUniswapV3Pool__factory.ts +13 -0
- package/types/factories/contracts/MentoInterfaces.sol/IBancorExchangeProvider__factory.ts +13 -0
- package/types/factories/contracts/fuseFaucet/Faucet copy.sol/DebugFaucet__factory.ts +945 -0
- package/types/factories/contracts/fuseFaucet/Faucet copy.sol/index.ts +4 -0
- package/types/factories/contracts/identity/IdentityV3__factory.ts +39 -1
- package/types/factories/contracts/index.ts +0 -1
- package/types/factories/contracts/mocks/GenericDistributionHelperTest.sol/CeloDistributionHelperTestHelper__factory.ts +1017 -0
- package/types/factories/contracts/mocks/GenericDistributionHelperTest.sol/GenericDistributionHelperTestHelper__factory.ts +1021 -0
- package/types/factories/contracts/mocks/GenericDistributionHelperTest.sol/GenericDistributionHelperTest__factory.ts +989 -0
- package/types/factories/contracts/mocks/GenericDistributionHelperTest.sol/index.ts +5 -0
- package/types/factories/contracts/mocks/index.ts +1 -0
- package/types/factories/contracts/reserve/GenericDistributionHelper__factory.ts +1 -1
- package/types/factories/contracts/utils/AdminWalletFuse__factory.ts +35 -1
- package/types/factories/contracts/utils/AdminWallet__factory.ts +35 -1
- package/types/factories/contracts/utils/BulkWhitelist__factory.ts +1 -1
- package/types/factories/contracts/utils/BuyFromReserveHelper__factory.ts +1 -1
- package/types/factories/contracts/utils/BuyGDClone.sol/BuyGDCloneV2__factory.ts +415 -0
- package/types/factories/contracts/utils/ProtoclUpgradeV4Mento.sol/ProtocolUpgradeV4Mento__factory.ts +1 -1
- package/types/factories/contracts/utils/UpdateReserveRatioAfterXDC.sol/MentoExchange__factory.ts +39 -0
- package/types/factories/contracts/utils/UpdateReserveRatioAfterXDC.sol/UpdateReserveRatioAfterXDC__factory.ts +110 -0
- package/types/factories/contracts/utils/UpdateReserveRatioAfterXDC.sol/index.ts +5 -0
- package/types/factories/contracts/utils/UpdateReserveSettingsForXdc.sol/MentoExchange__factory.ts +39 -0
- package/types/factories/contracts/utils/UpdateReserveSettingsForXdc.sol/UpdateReserveRatioAfterXDC__factory.ts +115 -0
- package/types/factories/contracts/utils/UpdateReserveSettingsForXdc.sol/index.ts +5 -0
- package/types/factories/contracts/utils/index.ts +2 -0
- package/types/hardhat.d.ts +54 -9
- package/types/index.ts +6 -0
- package/artifacts/contracts/IQuoter.sol/IQuoterV2.dbg.json +0 -4
- package/artifacts/contracts/IQuoter.sol/IQuoterV2.json +0 -211
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
import { ethers, upgrades, artifacts } from "hardhat";
|
|
2
|
+
import { loadFixture } from "@nomicfoundation/hardhat-network-helpers";
|
|
3
|
+
import { expect } from "chai";
|
|
4
|
+
import { GoodReserveCDai, DistributionBridgeMock, IGoodDollar, GenericDistributionHelperTestHelper } from "../../types";
|
|
5
|
+
import { createDAO, increaseTime } from "../helpers";
|
|
6
|
+
import * as waffle from "ethereum-waffle";
|
|
7
|
+
|
|
8
|
+
const BN = ethers.BigNumber;
|
|
9
|
+
export const NULL_ADDRESS = ethers.constants.AddressZero;
|
|
10
|
+
export const BLOCK_INTERVAL = 1;
|
|
11
|
+
|
|
12
|
+
describe("GenericDistributionHelper", () => {
|
|
13
|
+
let goodReserve: GoodReserveCDai;
|
|
14
|
+
let goodDollar: IGoodDollar, genericCall, avatar, founder, signers, setDAOAddress, nameService, cDai;
|
|
15
|
+
|
|
16
|
+
before(async () => {
|
|
17
|
+
[founder, ...signers] = await ethers.getSigners();
|
|
18
|
+
let {
|
|
19
|
+
controller: ctrl,
|
|
20
|
+
avatar: av,
|
|
21
|
+
gd,
|
|
22
|
+
identity,
|
|
23
|
+
setDAOAddress: sda,
|
|
24
|
+
setSchemes,
|
|
25
|
+
reserve,
|
|
26
|
+
cdaiAddress,
|
|
27
|
+
genericCall: gc,
|
|
28
|
+
nameService: ns
|
|
29
|
+
} = await loadFixture(createDAO);
|
|
30
|
+
|
|
31
|
+
nameService = ns;
|
|
32
|
+
genericCall = gc;
|
|
33
|
+
cDai = cdaiAddress;
|
|
34
|
+
avatar = av;
|
|
35
|
+
setDAOAddress = sda;
|
|
36
|
+
|
|
37
|
+
console.log("deployed dao", {
|
|
38
|
+
founder: founder.address,
|
|
39
|
+
gd,
|
|
40
|
+
identity,
|
|
41
|
+
avatar
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
goodDollar = (await ethers.getContractAt("IGoodDollar", gd)) as IGoodDollar;
|
|
45
|
+
|
|
46
|
+
console.log("deployed contribution, deploying reserve...", {
|
|
47
|
+
founder: founder.address
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
goodReserve = reserve as GoodReserveCDai;
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const fixture = async () => {
|
|
54
|
+
const mpbf = await artifacts.readArtifact("IStaticOracle");
|
|
55
|
+
|
|
56
|
+
let oracle = await waffle.deployMockContract(founder, mpbf.abi);
|
|
57
|
+
oracle.mock.quoteAllAvailablePoolsWithTimePeriod.returns(1e13, []);
|
|
58
|
+
oracle.mock.prepareAllAvailablePoolsWithTimePeriod.returns([]);
|
|
59
|
+
|
|
60
|
+
const distHelper = (await upgrades.deployProxy(
|
|
61
|
+
await ethers.getContractFactory("GenericDistributionHelperTestHelper"),
|
|
62
|
+
[
|
|
63
|
+
nameService.address,
|
|
64
|
+
oracle.address,
|
|
65
|
+
ethers.constants.AddressZero,
|
|
66
|
+
ethers.constants.AddressZero,
|
|
67
|
+
ethers.constants.AddressZero,
|
|
68
|
+
{
|
|
69
|
+
maxFee: "5000000000000000",
|
|
70
|
+
minBalanceForFees: "10000000000000000",
|
|
71
|
+
percentageToSellForFee: "5",
|
|
72
|
+
maxSlippage: "5"
|
|
73
|
+
}
|
|
74
|
+
],
|
|
75
|
+
{ kind: "uups" }
|
|
76
|
+
)) as GenericDistributionHelperTestHelper;
|
|
77
|
+
|
|
78
|
+
//make sure disthelper has enough native token so it doesnt try to swap G$s
|
|
79
|
+
await founder.sendTransaction({
|
|
80
|
+
to: distHelper.address,
|
|
81
|
+
value: ethers.constants.WeiPerEther
|
|
82
|
+
});
|
|
83
|
+
const bridge = (await ethers.deployContract("DistributionBridgeMock")) as DistributionBridgeMock;
|
|
84
|
+
|
|
85
|
+
const encodedCall = distHelper.interface.encodeFunctionData("setFeeSettings", [
|
|
86
|
+
{
|
|
87
|
+
maxFee: "5000000000000000",
|
|
88
|
+
minBalanceForFees: "10000000000000000",
|
|
89
|
+
percentageToSellForFee: "5",
|
|
90
|
+
maxSlippage: "5"
|
|
91
|
+
}
|
|
92
|
+
]);
|
|
93
|
+
|
|
94
|
+
await genericCall(distHelper.address, encodedCall, avatar.address, 0);
|
|
95
|
+
await distHelper.setBridges(bridge.address);
|
|
96
|
+
|
|
97
|
+
return { distHelper, bridge, oracle };
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
it("should not allow to add recipient", async () => {
|
|
101
|
+
const { distHelper } = await loadFixture(fixture);
|
|
102
|
+
|
|
103
|
+
const recipient = signers[0];
|
|
104
|
+
|
|
105
|
+
await expect(
|
|
106
|
+
distHelper.addOrUpdateRecipient({
|
|
107
|
+
bps: 3000,
|
|
108
|
+
chainId: 42220,
|
|
109
|
+
addr: recipient.address,
|
|
110
|
+
transferType: 0
|
|
111
|
+
})
|
|
112
|
+
).to.be.revertedWith(/is missing role 0x0000000000000000000000000000000000000000000000000000000000000000/);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it("should allow to add recipient by avatar", async () => {
|
|
116
|
+
const { distHelper } = await loadFixture(fixture);
|
|
117
|
+
|
|
118
|
+
const recipient = signers[0];
|
|
119
|
+
|
|
120
|
+
const encodedCall = distHelper.interface.encodeFunctionData("addOrUpdateRecipient", [
|
|
121
|
+
{
|
|
122
|
+
bps: 3000,
|
|
123
|
+
chainId: 42220,
|
|
124
|
+
addr: recipient.address,
|
|
125
|
+
transferType: 0
|
|
126
|
+
}
|
|
127
|
+
]);
|
|
128
|
+
|
|
129
|
+
await genericCall(distHelper.address, encodedCall, avatar.address, 0);
|
|
130
|
+
const dr = await distHelper.distributionRecipients(0);
|
|
131
|
+
expect(dr.addr).to.equal(recipient.address);
|
|
132
|
+
expect(dr.chainId).to.equal(42220);
|
|
133
|
+
expect(dr.bps).to.equal(3000);
|
|
134
|
+
expect(dr.transferType).to.equal(0);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it("should allow to update recipient by avatar", async () => {
|
|
138
|
+
const { distHelper } = await loadFixture(fixture);
|
|
139
|
+
|
|
140
|
+
const recipient = signers[0];
|
|
141
|
+
|
|
142
|
+
let encodedCall = distHelper.interface.encodeFunctionData("addOrUpdateRecipient", [
|
|
143
|
+
{
|
|
144
|
+
bps: 1000,
|
|
145
|
+
chainId: 4447,
|
|
146
|
+
addr: recipient.address,
|
|
147
|
+
transferType: 1
|
|
148
|
+
}
|
|
149
|
+
]);
|
|
150
|
+
|
|
151
|
+
await genericCall(distHelper.address, encodedCall, avatar.address, 0);
|
|
152
|
+
|
|
153
|
+
encodedCall = distHelper.interface.encodeFunctionData("addOrUpdateRecipient", [
|
|
154
|
+
{
|
|
155
|
+
bps: 1500,
|
|
156
|
+
chainId: 45,
|
|
157
|
+
addr: recipient.address,
|
|
158
|
+
transferType: 0
|
|
159
|
+
}
|
|
160
|
+
]);
|
|
161
|
+
|
|
162
|
+
await genericCall(distHelper.address, encodedCall, avatar.address, 0);
|
|
163
|
+
|
|
164
|
+
const updEvents = await distHelper.queryFilter(distHelper.filters.RecipientUpdated());
|
|
165
|
+
const addEvents = await distHelper.queryFilter(distHelper.filters.RecipientAdded());
|
|
166
|
+
|
|
167
|
+
const dr = await distHelper.distributionRecipients(0);
|
|
168
|
+
expect(dr.addr).to.equal(recipient.address);
|
|
169
|
+
expect(dr.chainId).to.equal(45);
|
|
170
|
+
expect(dr.bps).to.equal(1500);
|
|
171
|
+
expect(dr.transferType).to.equal(0);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it("should distribute via layerzero bridge", async () => {
|
|
175
|
+
const { distHelper, bridge } = await loadFixture(fixture);
|
|
176
|
+
|
|
177
|
+
const recipient = signers[0];
|
|
178
|
+
|
|
179
|
+
let encodedCall = distHelper.interface.encodeFunctionData("addOrUpdateRecipient", [
|
|
180
|
+
{
|
|
181
|
+
bps: 2000,
|
|
182
|
+
chainId: 42220,
|
|
183
|
+
addr: recipient.address,
|
|
184
|
+
transferType: 0
|
|
185
|
+
}
|
|
186
|
+
]);
|
|
187
|
+
|
|
188
|
+
await genericCall(distHelper.address, encodedCall, avatar.address, 0);
|
|
189
|
+
|
|
190
|
+
await goodDollar.mint(distHelper.address, "100000000000");
|
|
191
|
+
await founder.sendTransaction({
|
|
192
|
+
to: distHelper.address,
|
|
193
|
+
value: ethers.constants.WeiPerEther
|
|
194
|
+
});
|
|
195
|
+
await distHelper.onDistribution("100000000000");
|
|
196
|
+
expect(await goodDollar.allowance(distHelper.address, bridge.address)).to.equal((100000000000 * 2000) / 10000);
|
|
197
|
+
|
|
198
|
+
const events = await bridge.queryFilter(bridge.filters.BridgeLz());
|
|
199
|
+
expect(events[0].args.recipient).to.equal(recipient.address);
|
|
200
|
+
expect(events[0].args.amount).to.equal((100000000000 * 2000) / 10000);
|
|
201
|
+
expect(events[0].args.chainId).to.equal(42220);
|
|
202
|
+
expect(events[0].args.fee).to.equal(5e14);
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
it("should distribute via transferAndCall", async () => {
|
|
206
|
+
const { distHelper, bridge } = await loadFixture(fixture);
|
|
207
|
+
|
|
208
|
+
const recipient = signers[0];
|
|
209
|
+
|
|
210
|
+
let encodedCall = distHelper.interface.encodeFunctionData("addOrUpdateRecipient", [
|
|
211
|
+
{
|
|
212
|
+
bps: 2555,
|
|
213
|
+
chainId: 4447,
|
|
214
|
+
addr: signers[0].address,
|
|
215
|
+
transferType: 2
|
|
216
|
+
}
|
|
217
|
+
]);
|
|
218
|
+
|
|
219
|
+
await genericCall(distHelper.address, encodedCall, avatar.address, 0);
|
|
220
|
+
|
|
221
|
+
await goodDollar.mint(distHelper.address, "100000000000");
|
|
222
|
+
await distHelper.onDistribution("100000000000");
|
|
223
|
+
expect(await goodDollar.balanceOf(signers[0].address)).to.equal((100000000000 * 2555) / 10000);
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
it("should distribute to multiple recipients", async () => {
|
|
227
|
+
const { distHelper, bridge } = await loadFixture(fixture);
|
|
228
|
+
|
|
229
|
+
const recipient = signers[0];
|
|
230
|
+
|
|
231
|
+
let encodedCall = distHelper.interface.encodeFunctionData("addOrUpdateRecipient", [
|
|
232
|
+
{
|
|
233
|
+
bps: 2555,
|
|
234
|
+
chainId: 4447,
|
|
235
|
+
addr: signers[0].address,
|
|
236
|
+
transferType: 1
|
|
237
|
+
}
|
|
238
|
+
]);
|
|
239
|
+
|
|
240
|
+
await genericCall(distHelper.address, encodedCall, avatar.address, 0);
|
|
241
|
+
|
|
242
|
+
encodedCall = distHelper.interface.encodeFunctionData("addOrUpdateRecipient", [
|
|
243
|
+
{
|
|
244
|
+
bps: 1000,
|
|
245
|
+
chainId: 4447,
|
|
246
|
+
addr: signers[1].address,
|
|
247
|
+
transferType: 1
|
|
248
|
+
}
|
|
249
|
+
]);
|
|
250
|
+
|
|
251
|
+
await genericCall(distHelper.address, encodedCall, avatar.address, 0);
|
|
252
|
+
|
|
253
|
+
encodedCall = distHelper.interface.encodeFunctionData("addOrUpdateRecipient", [
|
|
254
|
+
{
|
|
255
|
+
bps: 5,
|
|
256
|
+
chainId: 4447,
|
|
257
|
+
addr: signers[2].address,
|
|
258
|
+
transferType: 2
|
|
259
|
+
}
|
|
260
|
+
]);
|
|
261
|
+
|
|
262
|
+
await genericCall(distHelper.address, encodedCall, avatar.address, 0);
|
|
263
|
+
|
|
264
|
+
await goodDollar.mint(distHelper.address, "100000000000");
|
|
265
|
+
await distHelper.onDistribution("100000000000");
|
|
266
|
+
expect(await goodDollar.balanceOf(signers[0].address)).to.equal((100000000000 * 2555) / 10000);
|
|
267
|
+
expect(await goodDollar.balanceOf(signers[1].address)).to.equal((100000000000 * 1000) / 10000);
|
|
268
|
+
expect(await goodDollar.balanceOf(signers[2].address)).to.equal((100000000000 * 5) / 10000);
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
it("should emit distribution event for multiple recipients", async () => {
|
|
272
|
+
const { distHelper, bridge } = await loadFixture(fixture);
|
|
273
|
+
|
|
274
|
+
let encodedCall = distHelper.interface.encodeFunctionData("addOrUpdateRecipient", [
|
|
275
|
+
{
|
|
276
|
+
bps: 2555,
|
|
277
|
+
chainId: 122,
|
|
278
|
+
addr: signers[0].address,
|
|
279
|
+
transferType: 0
|
|
280
|
+
}
|
|
281
|
+
]);
|
|
282
|
+
|
|
283
|
+
await genericCall(distHelper.address, encodedCall, avatar.address, 0);
|
|
284
|
+
|
|
285
|
+
encodedCall = distHelper.interface.encodeFunctionData("addOrUpdateRecipient", [
|
|
286
|
+
{
|
|
287
|
+
bps: 1000,
|
|
288
|
+
chainId: 4447,
|
|
289
|
+
addr: signers[1].address,
|
|
290
|
+
transferType: 1
|
|
291
|
+
}
|
|
292
|
+
]);
|
|
293
|
+
|
|
294
|
+
await genericCall(distHelper.address, encodedCall, avatar.address, 0);
|
|
295
|
+
|
|
296
|
+
encodedCall = distHelper.interface.encodeFunctionData("addOrUpdateRecipient", [
|
|
297
|
+
{
|
|
298
|
+
bps: 5,
|
|
299
|
+
chainId: 4447,
|
|
300
|
+
addr: signers[2].address,
|
|
301
|
+
transferType: 2
|
|
302
|
+
}
|
|
303
|
+
]);
|
|
304
|
+
|
|
305
|
+
await genericCall(distHelper.address, encodedCall, avatar.address, 0);
|
|
306
|
+
|
|
307
|
+
await goodDollar.mint(distHelper.address, "100000000000");
|
|
308
|
+
await distHelper.onDistribution("100000000000");
|
|
309
|
+
|
|
310
|
+
const DistributionEvents = await distHelper.queryFilter(distHelper.filters.Distribution());
|
|
311
|
+
expect(DistributionEvents[0].args.distributionRecipients[0].addr).eq(signers[0].address);
|
|
312
|
+
expect(DistributionEvents[0].args.distributionRecipients[1].addr).eq(signers[1].address);
|
|
313
|
+
expect(DistributionEvents[0].args.distributionRecipients[2].addr).eq(signers[2].address);
|
|
314
|
+
});
|
|
315
|
+
});
|
|
@@ -13,19 +13,10 @@ const ONE_DAY = 86400;
|
|
|
13
13
|
describe("UBIScheme cycle", () => {
|
|
14
14
|
let goodDollar, firstClaimPool;
|
|
15
15
|
let reputation;
|
|
16
|
-
let root,
|
|
17
|
-
acct,
|
|
18
|
-
claimer1,
|
|
19
|
-
claimer2,
|
|
20
|
-
claimer3,
|
|
21
|
-
signers,
|
|
22
|
-
nameService,
|
|
23
|
-
genericCall,
|
|
24
|
-
ubiScheme: UBIScheme;
|
|
16
|
+
let root, acct, claimer1, claimer2, claimer3, signers, nameService, genericCall, ubiScheme: UBIScheme;
|
|
25
17
|
|
|
26
18
|
before(async () => {
|
|
27
|
-
[root, acct, claimer1, claimer2, claimer3, ...signers] =
|
|
28
|
-
await ethers.getSigners();
|
|
19
|
+
[root, acct, claimer1, claimer2, claimer3, ...signers] = await ethers.getSigners();
|
|
29
20
|
|
|
30
21
|
const deployedDAO = await loadFixture(createDAO);
|
|
31
22
|
let {
|
|
@@ -64,9 +55,7 @@ describe("UBIScheme cycle", () => {
|
|
|
64
55
|
|
|
65
56
|
it("should be able to change cycleLength if avatar", async () => {
|
|
66
57
|
// initializing the ubi
|
|
67
|
-
let encodedCall = ubiScheme.interface.encodeFunctionData("setCycleLength", [
|
|
68
|
-
8
|
|
69
|
-
]);
|
|
58
|
+
let encodedCall = ubiScheme.interface.encodeFunctionData("setCycleLength", [8]);
|
|
70
59
|
await genericCall(ubiScheme.address, encodedCall);
|
|
71
60
|
expect(await ubiScheme.cycleLength()).to.be.equal(8);
|
|
72
61
|
});
|
|
@@ -81,10 +70,7 @@ describe("UBIScheme cycle", () => {
|
|
|
81
70
|
|
|
82
71
|
it("should set ubischeme", async () => {
|
|
83
72
|
// initializing the ubi
|
|
84
|
-
let encodedCall = firstClaimPool.interface.encodeFunctionData(
|
|
85
|
-
"setUBIScheme",
|
|
86
|
-
[ubiScheme.address]
|
|
87
|
-
);
|
|
73
|
+
let encodedCall = firstClaimPool.interface.encodeFunctionData("setUBIScheme", [ubiScheme.address]);
|
|
88
74
|
|
|
89
75
|
await genericCall(firstClaimPool.address, encodedCall);
|
|
90
76
|
// await firstClaimPool.start();
|
|
@@ -99,9 +85,7 @@ describe("UBIScheme cycle", () => {
|
|
|
99
85
|
let currentCycle = await ubiScheme.currentCycleLength();
|
|
100
86
|
let dailyAmount = await ubiScheme.dailyUbi();
|
|
101
87
|
expect(currentCycle.toNumber()).to.be.gt(0);
|
|
102
|
-
const cycleEvent = transaction.events.find(
|
|
103
|
-
e => e.event === "UBICycleCalculated"
|
|
104
|
-
);
|
|
88
|
+
const cycleEvent = transaction.events.find(e => e.event === "UBICycleCalculated");
|
|
105
89
|
console.log({
|
|
106
90
|
dailyAmount: dailyAmount.toString(),
|
|
107
91
|
event: cycleEvent.args
|
|
@@ -117,50 +101,40 @@ describe("UBIScheme cycle", () => {
|
|
|
117
101
|
await ubiScheme.connect(claimer2).claim();
|
|
118
102
|
increaseTime(ONE_DAY);
|
|
119
103
|
let transaction = await ubiScheme.connect(claimer2).claim();
|
|
120
|
-
expect(
|
|
121
|
-
await
|
|
122
|
-
)
|
|
123
|
-
expect(
|
|
124
|
-
|
|
125
|
-
).to.be.equal(125000);
|
|
126
|
-
expect(
|
|
127
|
-
await ubiScheme.currentDayInCycle().then(_ => _.toNumber())
|
|
128
|
-
).to.be.equal(1); //1 day passed
|
|
104
|
+
expect(await goodDollar.balanceOf(claimer2.address).then(_ => _.toNumber())).to.be.equal(
|
|
105
|
+
125 + (await ubiScheme.dailyUbi().then(_ => _.toNumber()))
|
|
106
|
+
); //first day 125 , second claim 125000 wei daily pool divided by 1000 active users = 125
|
|
107
|
+
expect(await ubiScheme.dailyCyclePool().then(_ => _.toNumber())).to.be.equal(125000);
|
|
108
|
+
expect(await ubiScheme.currentDayInCycle().then(_ => _.toNumber())).to.be.equal(1); //1 day passed
|
|
129
109
|
});
|
|
130
110
|
|
|
131
111
|
it("should calculate next cycle even if day passed without claims(setDay)", async () => {
|
|
132
112
|
increaseTime(ONE_DAY * 9);
|
|
133
|
-
expect(
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
113
|
+
expect(await ubiScheme.currentDayInCycle().then(_ => _.toNumber())).to.be.equal(10); //10 days passed total
|
|
114
|
+
|
|
115
|
+
const claimerBalanceBefore = await goodDollar.balanceOf(claimer1.address);
|
|
116
|
+
const minActiveUsers = await ubiScheme.minActiveUsers();
|
|
117
|
+
let dailyClaimAmount = (await ubiScheme.dailyCyclePool()).div(minActiveUsers); //initialy we have by default min 1000 active users
|
|
118
|
+
const estimatedUbi = await ubiScheme.estimateNextDailyUBI();
|
|
119
|
+
let totalClaimed = 0;
|
|
120
|
+
const currentDay = (await ubiScheme.currentDay()).toNumber();
|
|
121
|
+
for (let i = currentDay; i >= 0; i--) {
|
|
122
|
+
totalClaimed += (await ubiScheme.claimDay(i)).claimAmount.toNumber();
|
|
123
|
+
}
|
|
137
124
|
let transaction = await (await ubiScheme.connect(claimer1).claim()).wait(); //claims in new ubi cycle
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
expect(await goodDollar.balanceOf(claimer1.address)).to.be.equal(
|
|
141
|
-
dailyClaimAmount.add(125)
|
|
142
|
-
); //intial 10 from first claim pool + daily
|
|
143
|
-
const cycleEvent = transaction.events.find(
|
|
144
|
-
e => e.event === "UBICycleCalculated"
|
|
145
|
-
);
|
|
125
|
+
const cycleEvent = transaction.events.find(e => e.event === "UBICycleCalculated");
|
|
146
126
|
|
|
127
|
+
expect(await goodDollar.balanceOf(claimer1.address)).to.be.equal(claimerBalanceBefore.add(dailyClaimAmount)); //intial 10 from first claim pool + daily
|
|
128
|
+
expect(dailyClaimAmount).eq(estimatedUbi);
|
|
147
129
|
expect(cycleEvent).to.be.not.empty;
|
|
148
|
-
|
|
149
|
-
expect(
|
|
150
|
-
await ubiScheme.currentDayInCycle().then(_ => _.toNumber())
|
|
151
|
-
).to.be.equal(0); //new cycle started
|
|
130
|
+
expect(await ubiScheme.currentDayInCycle().then(_ => _.toNumber())).to.be.equal(0); //new cycle started
|
|
152
131
|
//intial balance on cycle start 1000000 - 375(3 user that claimed in previous tests) = 99625, divide by cycle length (8) = 124953
|
|
153
|
-
expect(cycleEvent.args.dailyUBIPool).to.be.equal(
|
|
154
|
-
(BigInt(1000000) - BigInt(375)) / BigInt(8)
|
|
155
|
-
);
|
|
132
|
+
expect(cycleEvent.args.dailyUBIPool).to.be.equal((BigInt(1000000) - BigInt(totalClaimed)) / BigInt(8));
|
|
156
133
|
});
|
|
157
134
|
|
|
158
135
|
it("should calculate cycle early if we can increase current daily pool", async () => {
|
|
159
136
|
//increase ubi pool balance
|
|
160
|
-
let encoded = goodDollar.interface.encodeFunctionData("mint", [
|
|
161
|
-
ubiScheme.address,
|
|
162
|
-
400000
|
|
163
|
-
]);
|
|
137
|
+
let encoded = goodDollar.interface.encodeFunctionData("mint", [ubiScheme.address, 400000]);
|
|
164
138
|
await genericCall(goodDollar.address, encoded);
|
|
165
139
|
let balance = await goodDollar.balanceOf(ubiScheme.address);
|
|
166
140
|
|
|
@@ -173,9 +147,7 @@ describe("UBIScheme cycle", () => {
|
|
|
173
147
|
const estimated = await ubiScheme.estimateNextDailyUBI();
|
|
174
148
|
await increaseTime(ONE_DAY); //make sure
|
|
175
149
|
let transaction = await (await ubiScheme.connect(claimer1).claim()).wait();
|
|
176
|
-
const cycleEvent = transaction.events.find(
|
|
177
|
-
e => e.event === "UBICycleCalculated"
|
|
178
|
-
);
|
|
150
|
+
const cycleEvent = transaction.events.find(e => e.event === "UBICycleCalculated");
|
|
179
151
|
const dailyUBI = await ubiScheme.dailyUbi();
|
|
180
152
|
expect(dailyUBI).to.eq(estimated); //the estimated before actual calculation should be correct, ie equal to actual dailyUBI calculated after first claim.
|
|
181
153
|
expect(cycleEvent).to.be.not.empty;
|
|
@@ -187,10 +159,7 @@ describe("UBIScheme cycle", () => {
|
|
|
187
159
|
|
|
188
160
|
it("should not calculate cycle early if not possible to increase daily ubi pool", async () => {
|
|
189
161
|
//increase ubi pool balance
|
|
190
|
-
let encoded = goodDollar.interface.encodeFunctionData("mint", [
|
|
191
|
-
ubiScheme.address,
|
|
192
|
-
100
|
|
193
|
-
]);
|
|
162
|
+
let encoded = goodDollar.interface.encodeFunctionData("mint", [ubiScheme.address, 100]);
|
|
194
163
|
await genericCall(goodDollar.address, encoded);
|
|
195
164
|
let balance = await goodDollar.balanceOf(ubiScheme.address);
|
|
196
165
|
const curCycleLen = await ubiScheme.cycleLength();
|
|
@@ -200,9 +169,7 @@ describe("UBIScheme cycle", () => {
|
|
|
200
169
|
|
|
201
170
|
await increaseTime(ONE_DAY); //make sure
|
|
202
171
|
let transaction = await (await ubiScheme.connect(claimer1).claim()).wait();
|
|
203
|
-
const cycleEvent = transaction.events.find(
|
|
204
|
-
e => e.event === "UBICycleCalculated"
|
|
205
|
-
);
|
|
172
|
+
const cycleEvent = transaction.events.find(e => e.event === "UBICycleCalculated");
|
|
206
173
|
expect(cycleEvent).to.be.undefined;
|
|
207
174
|
});
|
|
208
175
|
});
|
|
@@ -24,6 +24,7 @@ import type {
|
|
|
24
24
|
|
|
25
25
|
export interface IUniswapV3PoolInterface extends utils.Interface {
|
|
26
26
|
functions: {
|
|
27
|
+
"fee()": FunctionFragment;
|
|
27
28
|
"initialize(uint160)": FunctionFragment;
|
|
28
29
|
"slot0()": FunctionFragment;
|
|
29
30
|
"token0()": FunctionFragment;
|
|
@@ -31,9 +32,10 @@ export interface IUniswapV3PoolInterface extends utils.Interface {
|
|
|
31
32
|
};
|
|
32
33
|
|
|
33
34
|
getFunction(
|
|
34
|
-
nameOrSignatureOrTopic: "initialize" | "slot0" | "token0" | "token1"
|
|
35
|
+
nameOrSignatureOrTopic: "fee" | "initialize" | "slot0" | "token0" | "token1"
|
|
35
36
|
): FunctionFragment;
|
|
36
37
|
|
|
38
|
+
encodeFunctionData(functionFragment: "fee", values?: undefined): string;
|
|
37
39
|
encodeFunctionData(
|
|
38
40
|
functionFragment: "initialize",
|
|
39
41
|
values: [BigNumberish]
|
|
@@ -42,6 +44,7 @@ export interface IUniswapV3PoolInterface extends utils.Interface {
|
|
|
42
44
|
encodeFunctionData(functionFragment: "token0", values?: undefined): string;
|
|
43
45
|
encodeFunctionData(functionFragment: "token1", values?: undefined): string;
|
|
44
46
|
|
|
47
|
+
decodeFunctionResult(functionFragment: "fee", data: BytesLike): Result;
|
|
45
48
|
decodeFunctionResult(functionFragment: "initialize", data: BytesLike): Result;
|
|
46
49
|
decodeFunctionResult(functionFragment: "slot0", data: BytesLike): Result;
|
|
47
50
|
decodeFunctionResult(functionFragment: "token0", data: BytesLike): Result;
|
|
@@ -77,6 +80,8 @@ export interface IUniswapV3Pool extends BaseContract {
|
|
|
77
80
|
removeListener: OnEvent<this>;
|
|
78
81
|
|
|
79
82
|
functions: {
|
|
83
|
+
fee(overrides?: CallOverrides): Promise<[number]>;
|
|
84
|
+
|
|
80
85
|
initialize(
|
|
81
86
|
sqrtPriceX96: BigNumberish,
|
|
82
87
|
overrides?: Overrides & { from?: string }
|
|
@@ -101,6 +106,8 @@ export interface IUniswapV3Pool extends BaseContract {
|
|
|
101
106
|
token1(overrides?: CallOverrides): Promise<[string]>;
|
|
102
107
|
};
|
|
103
108
|
|
|
109
|
+
fee(overrides?: CallOverrides): Promise<number>;
|
|
110
|
+
|
|
104
111
|
initialize(
|
|
105
112
|
sqrtPriceX96: BigNumberish,
|
|
106
113
|
overrides?: Overrides & { from?: string }
|
|
@@ -125,6 +132,8 @@ export interface IUniswapV3Pool extends BaseContract {
|
|
|
125
132
|
token1(overrides?: CallOverrides): Promise<string>;
|
|
126
133
|
|
|
127
134
|
callStatic: {
|
|
135
|
+
fee(overrides?: CallOverrides): Promise<number>;
|
|
136
|
+
|
|
128
137
|
initialize(
|
|
129
138
|
sqrtPriceX96: BigNumberish,
|
|
130
139
|
overrides?: CallOverrides
|
|
@@ -152,6 +161,8 @@ export interface IUniswapV3Pool extends BaseContract {
|
|
|
152
161
|
filters: {};
|
|
153
162
|
|
|
154
163
|
estimateGas: {
|
|
164
|
+
fee(overrides?: CallOverrides): Promise<BigNumber>;
|
|
165
|
+
|
|
155
166
|
initialize(
|
|
156
167
|
sqrtPriceX96: BigNumberish,
|
|
157
168
|
overrides?: Overrides & { from?: string }
|
|
@@ -165,6 +176,8 @@ export interface IUniswapV3Pool extends BaseContract {
|
|
|
165
176
|
};
|
|
166
177
|
|
|
167
178
|
populateTransaction: {
|
|
179
|
+
fee(overrides?: CallOverrides): Promise<PopulatedTransaction>;
|
|
180
|
+
|
|
168
181
|
initialize(
|
|
169
182
|
sqrtPriceX96: BigNumberish,
|
|
170
183
|
overrides?: Overrides & { from?: string }
|
|
@@ -55,6 +55,7 @@ export declare namespace IBancorExchangeProvider {
|
|
|
55
55
|
|
|
56
56
|
export interface IBancorExchangeProviderInterface extends utils.Interface {
|
|
57
57
|
functions: {
|
|
58
|
+
"AVATAR()": FunctionFragment;
|
|
58
59
|
"createExchange((address,address,uint256,uint256,uint32,uint32))": FunctionFragment;
|
|
59
60
|
"currentPrice(bytes32)": FunctionFragment;
|
|
60
61
|
"destroyExchange(bytes32,uint256)": FunctionFragment;
|
|
@@ -65,6 +66,7 @@ export interface IBancorExchangeProviderInterface extends utils.Interface {
|
|
|
65
66
|
|
|
66
67
|
getFunction(
|
|
67
68
|
nameOrSignatureOrTopic:
|
|
69
|
+
| "AVATAR"
|
|
68
70
|
| "createExchange"
|
|
69
71
|
| "currentPrice"
|
|
70
72
|
| "destroyExchange"
|
|
@@ -73,6 +75,7 @@ export interface IBancorExchangeProviderInterface extends utils.Interface {
|
|
|
73
75
|
| "setExitContribution"
|
|
74
76
|
): FunctionFragment;
|
|
75
77
|
|
|
78
|
+
encodeFunctionData(functionFragment: "AVATAR", values?: undefined): string;
|
|
76
79
|
encodeFunctionData(
|
|
77
80
|
functionFragment: "createExchange",
|
|
78
81
|
values: [IBancorExchangeProvider.PoolExchangeStruct]
|
|
@@ -98,6 +101,7 @@ export interface IBancorExchangeProviderInterface extends utils.Interface {
|
|
|
98
101
|
values: [BytesLike, BigNumberish]
|
|
99
102
|
): string;
|
|
100
103
|
|
|
104
|
+
decodeFunctionResult(functionFragment: "AVATAR", data: BytesLike): Result;
|
|
101
105
|
decodeFunctionResult(
|
|
102
106
|
functionFragment: "createExchange",
|
|
103
107
|
data: BytesLike
|
|
@@ -219,6 +223,8 @@ export interface IBancorExchangeProvider extends BaseContract {
|
|
|
219
223
|
removeListener: OnEvent<this>;
|
|
220
224
|
|
|
221
225
|
functions: {
|
|
226
|
+
AVATAR(overrides?: CallOverrides): Promise<[string]>;
|
|
227
|
+
|
|
222
228
|
createExchange(
|
|
223
229
|
exchange: IBancorExchangeProvider.PoolExchangeStruct,
|
|
224
230
|
overrides?: Overrides & { from?: string }
|
|
@@ -255,6 +261,8 @@ export interface IBancorExchangeProvider extends BaseContract {
|
|
|
255
261
|
): Promise<ContractTransaction>;
|
|
256
262
|
};
|
|
257
263
|
|
|
264
|
+
AVATAR(overrides?: CallOverrides): Promise<string>;
|
|
265
|
+
|
|
258
266
|
createExchange(
|
|
259
267
|
exchange: IBancorExchangeProvider.PoolExchangeStruct,
|
|
260
268
|
overrides?: Overrides & { from?: string }
|
|
@@ -285,6 +293,8 @@ export interface IBancorExchangeProvider extends BaseContract {
|
|
|
285
293
|
): Promise<ContractTransaction>;
|
|
286
294
|
|
|
287
295
|
callStatic: {
|
|
296
|
+
AVATAR(overrides?: CallOverrides): Promise<string>;
|
|
297
|
+
|
|
288
298
|
createExchange(
|
|
289
299
|
exchange: IBancorExchangeProvider.PoolExchangeStruct,
|
|
290
300
|
overrides?: CallOverrides
|
|
@@ -359,6 +369,8 @@ export interface IBancorExchangeProvider extends BaseContract {
|
|
|
359
369
|
};
|
|
360
370
|
|
|
361
371
|
estimateGas: {
|
|
372
|
+
AVATAR(overrides?: CallOverrides): Promise<BigNumber>;
|
|
373
|
+
|
|
362
374
|
createExchange(
|
|
363
375
|
exchange: IBancorExchangeProvider.PoolExchangeStruct,
|
|
364
376
|
overrides?: Overrides & { from?: string }
|
|
@@ -390,6 +402,8 @@ export interface IBancorExchangeProvider extends BaseContract {
|
|
|
390
402
|
};
|
|
391
403
|
|
|
392
404
|
populateTransaction: {
|
|
405
|
+
AVATAR(overrides?: CallOverrides): Promise<PopulatedTransaction>;
|
|
406
|
+
|
|
393
407
|
createExchange(
|
|
394
408
|
exchange: IBancorExchangeProvider.PoolExchangeStruct,
|
|
395
409
|
overrides?: Overrides & { from?: string }
|