Skip to content

Commit

Permalink
Fix testing errors, extend tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ChristianBorst committed Jun 12, 2024
1 parent 6663755 commit aca227f
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 88 deletions.
20 changes: 19 additions & 1 deletion hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,25 @@ const DAI_TEST5 = vars.get(
);

const config: HardhatUserConfig = {
solidity: "0.8.19",
solidity: {
compilers: [
{
version: "0.8.19",
settings: {
optimizer: {
enabled: true,
runs: 1000000,
},
outputSelection: {
"*": {
"*": ["storageLayout"],
},
},
},
},
],
overrides: {},
},
networks: {
dai: {
url: "https://rpc.gnosischain.com",
Expand Down
162 changes: 87 additions & 75 deletions test/FixedPoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,20 @@ export const ZERO_ADDR = "0x0000000000000000000000000000000000000000"
export function toQ64 (val: number | BN.BigNumber): bigint {
var multFixed: BN.BigNumber;
if (typeof val === 'number') {
multFixed = BN.BigNumber(Math.round(val * PRECISION));
multFixed = BN.BigNumber(val);
} else {
multFixed = val.times(PRECISION);
multFixed = val;
}
let res = (multFixed.times(Q_64).div(BN.BigNumber(PRECISION)))
let res = (multFixed.times(Q_64).integerValue())
return BigInt(res.toFixed())
}

export function fromQ64 (val: bigint): BN.BigNumber {
return BN.BigNumber(val.toString()).times(PRECISION_BN).div(Q_64).div(PRECISION_BN);
return BN.BigNumber(val.toString()).div(Q_64);
}

describe('TestFixedMath', () => {
let fixed: TestFixedPoint
let fixed: TestFixedPoint;
const Q64_MIN = BN.BigNumber(2).pow(63).minus(1).negated();
const TT64 = BN.BigNumber(2).pow(64);
const TT128 = BN.BigNumber(2).pow(128);
Expand All @@ -38,94 +38,106 @@ describe('TestFixedMath', () => {
fixed = (await libFactory.deploy()) as unknown as TestFixedPoint;
})

it("addQ64", async () => {
let small = BigInt(1);
let result = await(fixed.testAddQ64(small, small));
expect(result).eq(BigInt(2));
});

it("mulQ64", async () => {
let result = await fixed.testMulQ64(toQ64(3.5).toString(), toQ64(5.25).toString())
let bn_fixed = fromQ64(result)
let expected = 18.375
let bn_expected = BN.BigNumber(expected)
expect(bn_fixed.eq(bn_expected));

bn_expected = TT64.minus(1)
let bn_result = await fixed.testMulQ64(toQ64(2**63-1), toQ64(2.0))
expect(fromQ64(bn_result).eq(bn_expected))
let result = await fixed.testMulQ64(toQ64(3.5).toString(), toQ64(5.25).toString());
let bn_fixed = fromQ64(result);
let bn_expected = BN.BigNumber("18.375");
expect(bn_fixed.eq(bn_expected)).to.be.true;

bn_expected = BN.BigNumber("340282366920938463463374607431768211456"); // 2^63 * 2 before fromQ64()
let bn_result = BN.BigNumber((await fixed.testMulQ64(toQ64((BN.BigNumber(2).pow(63))), toQ64(2))).toString());
expect(bn_result.eq(bn_expected)).to.be.true;

let BI_TT128M1 = BigInt(TT128.minus(1).toFixed())

result = await fixed.testMulQ64(BI_TT128M1, BI_TT128M1)
console.log("Got [" + result + "] expected [" + TT128.minus(1).pow(2).toFixed() + "]");
expect(fromQ64(result).eq(TT128.minus(1).pow(2)))
let BI_TT128M1 = BigInt(TT128.minus(1).toFixed());
let BN_TT128M1 = TT128.minus(1);
result = await fixed.testMulQ64(BI_TT128M1, BI_TT128M1);
bn_expected = BN_TT128M1.times(BN_TT128M1).div(TT64).integerValue();
expect(BN.BigNumber(result.toString()).eq(bn_expected)).to.be.true;

result = await fixed.testMulQ64(toQ64(1), toQ64(2.0))
expect(fromQ64(result).eq(2.0))
})
result = await fixed.testMulQ64(toQ64(1), toQ64(2.0));
expect(fromQ64(result).eq(2.0)).to.be.true;
});

it("mulQ64 Precision", async () => {
let result = await fixed.testMulQ64(BigInt(2)**BigInt(126), BigInt(2)**BigInt(127));
expect(result).to.equal(BigInt(2)**BigInt(189));
})
});

it("divQ64", async () => {
let result = await fixed.testDivQ64(toQ64(3.5), toQ64(0.125))
expect(fromQ64(result).eq(28.0));
})
let result = await fixed.testDivQ64(toQ64(3.5), toQ64(0.125));
expect(fromQ64(result).eq(28.0)).to.be.true;
});

it("divQ64 Precision", async () => {
let result = await fixed.testDivQ64(BigInt(2)**BigInt(126), BigInt(2)**BigInt(3));
expect(fromQ64(result).eq(BN.BigNumber(2).pow(129)));
})
expect(fromQ64(result).eq(BN.BigNumber(2).pow(123))).to.be.true;
});

// This test still uses Q64 numbers, but JS doesn't share the same concept of fixed point numbers
// that the solidity expects. So we pass Q64 numbers to the "Q128" functions
it("mulQ128.64", async () => {
console.log("3.5 * 5.25")
let result = await fixed.testMulQ128(toQ64(3.5).toString(), toQ64(5.25).toString())
let bn_fixed = fromQ64(result)
let expected = 18.375
let bn_expected = BN.BigNumber(expected)
expect(bn_fixed.eq(bn_expected));

console.log("((2^127)-1) * 2.0")
bn_expected = TT128.minus(1)
console.log("Calc expected")
let x = (BN.BigNumber(2).pow(127)).minus(1);
console.log("Calc x")
let bn_result = await fixed.testMulQ128(toQ64(x), toQ64(2.0))
console.log("bn result")
expect(fromQ64(bn_result).eq(bn_expected))
let a = toQ64(2)
let b = toQ64(2)
let result = await fixed.testMulQ128(a, b);
expect(fromQ64(result).eq(4)).to.be.true;

let bn_expected = TT128;
let x = (BN.BigNumber(2).pow(127));
let bn_result = await fixed.testMulQ128(toQ64(x), toQ64(2.0));
expect(fromQ64(bn_result).eq(bn_expected)).to.be.true;

console.log("((2^128)-2) * ((2^128)-2)")
let BI_TT192M1 = BigInt(TT192.minus(TT64).toFixed())
console.log("Calculating ", BI_TT192M1, " ^ 2")
result = await fixed.testMulQ128(BI_TT192M1, BI_TT192M1)
console.log("Got [" + result + "] expected [" + TT128.minus(1).pow(2).toFixed() + "]");
expect(fromQ64(result).eq(TT192.minus(1).pow(2)))

result = await fixed.testMulQ128(toQ64(1), toQ64(2.0))
expect(fromQ64(result).eq(2.0))
})
let target = BN.BigNumber(2).pow(191).minus(1);
x = (BN.BigNumber(2).pow(124));
let y = (target.div(x)); // Want x * y = 2^192 - 1
let expected = x.times(y).integerValue();
result = await fixed.testMulQ128(toQ64(x), toQ64(y));
expect(fromQ64(result).eq(expected)).to.be.true;

result = await fixed.testMulQ128(toQ64(1), toQ64(2.0));
expect(fromQ64(result).eq(2.0)).to.be.true;

x = BN.BigNumber(2).pow(128).minus(1)
y = BN.BigNumber(1.0)
expected = x.times(y).integerValue();
result = await fixed.testMulQ128(toQ64(x), toQ64(y));
expect(fromQ64(result).eq(expected)).to.be.true;
});

it("divQ128", async () => {
console.log("10^18 / 0.25")
let result = await fixed.testDivQ128(toQ64(10**18), toQ64(0.25))
expect(fromQ64(result).eq(4 * 10**18));
console.log("2^126 / 0.5")
let x = (BN.BigNumber(2).pow(126));
let y = 0.5;
result = await fixed.testDivQ128(toQ64(x), toQ64(y))
expect(fromQ64(result).eq(BN.BigNumber(2).pow(127)));
x = (BN.BigNumber(2).pow(127).minus(1));
console.log("2^127-1 / 0.5")
result = await fixed.testDivQ128(toQ64(x), toQ64(y))
expect(fromQ64(result).eq(BN.BigNumber(2).pow(128)));

x = BN.BigNumber(1)
y = 10000000000000000000000000
result = await fixed.testDivQ128(toQ64(x), toQ64(y))
expect(fromQ64(result).eq(BN.BigNumber(1).div(10000000000000000000000000)));

y = 100000000000000000000000000000000000000
result = await fixed.testDivQ128(toQ64(x), toQ64(y))
expect(fromQ64(result).eq(BN.BigNumber(1).div(100000000000000000000000000000000000000)));
})
let x = BN.BigNumber(18000000);
let y = BN.BigNumber(80855071);
let expected = BN.BigNumber("4106624225545135308");
let result = await fixed.testDivQ128(toQ64(x), toQ64(y));
expect(BN.BigNumber(result.toString()).eq(expected)).to.be.true;

x = BN.BigNumber(10).pow(18);
y = BN.BigNumber(1).div(4);
result = await fixed.testDivQ128(toQ64(x), toQ64(y));
expect(fromQ64(result).eq(4 * 10**18)).to.be.true;

x = (BN.BigNumber(2).pow(126));
y = BN.BigNumber(0.5);
result = await fixed.testDivQ128(toQ64(x), toQ64(y));
expect(fromQ64(result).eq(BN.BigNumber(2).pow(127))).to.be.true;

x = (BN.BigNumber(2).pow(127));
result = await fixed.testDivQ128(toQ64(x), toQ64(y));
expect(fromQ64(result).eq(BN.BigNumber(2).pow(128))).to.be.true;

x = BN.BigNumber(1);
y = BN.BigNumber(10000000000000000000000000);
result = await fixed.testDivQ128(toQ64(x), toQ64(y));
expect(fromQ64(result).eq(BN.BigNumber(1).div(10000000000000000000000000))).to.be.true;

y = BN.BigNumber(100000000000000000000000000000000000000);
result = await fixed.testDivQ128(toQ64(x), toQ64(y));
expect(fromQ64(result).eq(BN.BigNumber(1).div(100000000000000000000000000000000000000))).to.be.true;
});

})
28 changes: 16 additions & 12 deletions test/liquidERC20.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,10 @@ describe('TestLiquidERC20', () => {

for (let i = 0; i < signers.length; i++) {
for (let j = 0; j < erc20s.length; j++) {
expect(balanceBySignerBefore[i][j] + revenueByHolder[i][j] == balanceBySignerAfter[i][j]).to.be.true;
let before = balanceBySignerBefore[i][j];
let after = balanceBySignerAfter[i][j];
let rev = revenueByHolder[i][j];
expect(before.plus(rev).eq(after)).to.be.true;
}
}
});
Expand All @@ -148,7 +151,7 @@ describe('TestLiquidERC20', () => {
await claimRevenue(signers, token);
});

it("BigNumber Revenue Claim with Accounting", async () => {
it("BigNumberRevenue Claim z with Accounting", async () => {
let deployer = signers[0];
let numNFTs = randi(25) + 1;
let nfts = await deployLiquidNFTs(deployer, numNFTs, erc20s, erc20s.map((v) => 0));
Expand Down Expand Up @@ -178,7 +181,7 @@ describe('TestLiquidERC20', () => {
expect(actualIncrease.gte(acceptableIncrease)).to.be.true;
}
}
});
}).timeout(80000); // Increase the timeout to 80 seconds

it("Many Stakers BigNumber Revenue Claim", async () => {
let deployer = signers[0];
Expand All @@ -204,7 +207,7 @@ describe('TestLiquidERC20', () => {
await token.withdrawFromAllManagedNFTs();

await claimRevenue(holders, token);
}).timeout(80000); // Increase the timeout to 80 seconds
}).timeout(120000); // Increase the timeout to 80 seconds

it("BigNumber Three Phase Staking", async () => {
let deployer = signers[0];
Expand Down Expand Up @@ -292,7 +295,7 @@ describe('TestLiquidERC20', () => {
let actualRevenue = balanceBySignerAfter[i].map((v, j) => BN.BigNumber(v).minus(balanceBySignerBefore[i][j]));
actualRevenue.map((v, j) => expect(v.gte(acceptableRevenue[j])).to.be.true);
}
}).timeout(80000); // Increase the timeout to 80 seconds
}).timeout(120000); // Increase the timeout to 80 seconds

it("BigNumber Agent Staking", async () => {
const start = Date.now();
Expand Down Expand Up @@ -360,7 +363,7 @@ describe('TestLiquidERC20', () => {
}

let w = -1;
while (Date.now() - start < 60 * 1000) {
while (Date.now() - start < five_minutes) {
w += 1;
console.log("Withdrawal " + w)
for (let s = 0; s < stakerActionsPerWithdrawal; s++) {
Expand All @@ -376,6 +379,7 @@ describe('TestLiquidERC20', () => {
await stakeFromHolders([newStaker], token);
withdrawalData[w].stakers.push({signer: newStaker, stake: stake});
withdrawalData[w].totalStake = withdrawalData[w].totalStake.plus(stake);
console.log("Added staker " + newStaker.address + " with stake " + stake.toString());
} else if (action < 70 && withdrawalData[w].stakers.length > 0) {
// 30% chance of unstaking
let unstaker = withdrawalData[w].stakers[withdrawalData[w].stakers.length - 1];
Expand Down Expand Up @@ -487,13 +491,13 @@ describe('TestLiquidERC20', () => {

let acceptableIncrease = expectedRevenue.times(1 - acceptableError);
if (! actualIncrease.gte(acceptableIncrease)) {
console.log("Holder: " + holders[h].address + " ERC20: " + e + " Expected: " + expectedRevenue + " Actual: " + actualIncrease);
console.log("Holder: " + holders[h].address + " ERC20: " + await erc20s[e].getAddress() + " Expected: " + expectedRevenue.toFixed() + " Actual: " + actualIncrease.toFixed());
}
expect(actualIncrease.gte(acceptableIncrease)).to.be.true;
}
}
}
).timeout(1000 * 60 * 5); // Increase the timeout to 5 minutes
).timeout(1000 * 60 * 8); // Increase the timeout to 8 minutes
}
);

Expand Down Expand Up @@ -573,13 +577,13 @@ export async function claimRevenue(stakers: HardhatEthersSigner[], token: Liquid
}
}

export async function getSignerBalances(signers: HardhatEthersSigner[], erc20s: ERC20[]): Promise<number[][]> {
let balances: number[][] = [];
export async function getSignerBalances(signers: HardhatEthersSigner[], erc20s: ERC20[]): Promise<BN.BigNumber[][]> {
let balances: BN.BigNumber[][] = [];
for (let signer of signers) {
let signerBalances: number[] = [];
let signerBalances: BN.BigNumber[] = [];
for (let erc20 of erc20s) {
let balance = await erc20.balanceOf(signer.address);
signerBalances.push(Number.parseInt(balance.toString()));
signerBalances.push(BN.BigNumber(balance.toString()));
}
balances.push(signerBalances);
}
Expand Down

0 comments on commit aca227f

Please sign in to comment.