Skip to content

Commit

Permalink
test: restarting bmath echidna tests
Browse files Browse the repository at this point in the history
  • Loading branch information
wei3erHase committed Jul 25, 2024
1 parent 888ebe9 commit b0744ed
Show file tree
Hide file tree
Showing 3 changed files with 237 additions and 98 deletions.
1 change: 1 addition & 0 deletions crytic-export/combined_solc.json

Large diffs are not rendered by default.

236 changes: 236 additions & 0 deletions test/invariants/fuzz/BMath.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.25;

import {EchidnaTest} from '../helpers/AdvancedTestsUtils.sol';

import {BMath} from 'contracts/BMath.sol';

contract FuzzBMath is EchidnaTest {
event Log(string label, uint256 number);

BMath bmath;

uint256 BONE = 10 ** 18;
uint256 MIN_WEIGHT;
uint256 MAX_WEIGHT;
uint256 MAX_TOTAL_WEIGHT;
uint256 MIN_FEE;
uint256 MAX_FEE;

function setUp() public {
bmath = new BMath();

MIN_WEIGHT = bmath.MIN_WEIGHT();
MAX_WEIGHT = bmath.MAX_WEIGHT();
MAX_TOTAL_WEIGHT = bmath.MAX_TOTAL_WEIGHT();
MIN_FEE = bmath.MIN_FEE();
MAX_FEE = bmath.MAX_FEE();
}

// calcOutGivenIn should be inverse of calcInGivenOut
function testCalcInGivenOut_InvCalcInGivenOut(
uint256 tokenBalanceIn,
uint256 tokenWeightIn,
uint256 tokenBalanceOut,
uint256 tokenWeightOut,
uint256 tokenAmountIn,
uint256 swapFee
) public {
tokenWeightIn = clamp(tokenWeightIn, MIN_WEIGHT, MAX_WEIGHT);
tokenWeightOut = clamp(tokenWeightOut, MIN_WEIGHT, MAX_WEIGHT);
tokenAmountIn = clamp(tokenAmountIn, BONE, 1_000_000 ether);
tokenBalanceIn = clamp(tokenBalanceIn, BONE, type(uint256).max);
tokenBalanceOut = clamp(tokenBalanceOut, BONE, type(uint256).max);
swapFee = clamp(swapFee, MIN_FEE, MAX_FEE);

emit Log('tokenAmountIn', tokenAmountIn);

uint256 calc_tokenAmountOut =
bmath.calcOutGivenIn(tokenBalanceIn, tokenWeightIn, tokenBalanceOut, tokenWeightOut, tokenAmountIn, swapFee);
emit Log('calc_tokenAmountOut', calc_tokenAmountOut);

uint256 calc_tokenAmountIn =
bmath.calcInGivenOut(tokenBalanceOut, tokenWeightOut, tokenBalanceIn, tokenWeightIn, calc_tokenAmountOut, swapFee);
emit Log('calc_tokenAmountIn', calc_tokenAmountIn);

assert(
tokenAmountIn == calc_tokenAmountIn || tokenAmountIn > calc_tokenAmountIn
? tokenAmountIn - calc_tokenAmountIn < BONE
: calc_tokenAmountIn - tokenAmountIn < BONE
);
}

// calcInGivenOut should be inverse of calcOutGivenIn
function testCalcOutGivenIn_InvCalcOutGivenIn(
uint256 tokenBalanceIn,
uint256 tokenWeightIn,
uint256 tokenBalanceOut,
uint256 tokenWeightOut,
uint256 tokenAmountOut,
uint256 swapFee
) public {
tokenWeightIn = clamp(tokenWeightIn, MIN_WEIGHT, MAX_WEIGHT);
tokenWeightOut = clamp(tokenWeightOut, MIN_WEIGHT, MAX_WEIGHT);
tokenAmountOut = clamp(tokenAmountOut, BONE, 1_000_000 ether);
tokenBalanceIn = clamp(tokenBalanceIn, BONE, type(uint256).max);
tokenBalanceOut = clamp(tokenBalanceOut, BONE, type(uint256).max);

emit Log('tokenAmountOut', tokenAmountOut);

uint256 calc_tokenAmountIn =
bmath.calcInGivenOut(tokenBalanceOut, tokenWeightOut, tokenBalanceIn, tokenWeightIn, tokenAmountOut, swapFee);
emit Log('calc_tokenAmountIn', calc_tokenAmountIn);

uint256 calc_tokenAmountOut =
bmath.calcOutGivenIn(tokenBalanceIn, tokenWeightIn, tokenBalanceOut, tokenWeightOut, calc_tokenAmountIn, swapFee);
emit Log('calc_tokenAmountOut', calc_tokenAmountOut);

assert(tokenAmountOut == calc_tokenAmountOut);
}

// calcSingleInGivenPoolOut should be inverse of calcPoolOutGivenSingleIn
function testCalcSingleInGivenPoolOut_InvCalcPoolOutGivenSingle(
uint256 tokenBalanceIn,
uint256 tokenWeightIn,
uint256 poolSupply,
uint256 totalWeight,
uint256 tokenAmountOut,
uint256 swapFee
) public {
tokenWeightIn = clamp(tokenWeightIn, MIN_WEIGHT, MAX_WEIGHT);
totalWeight = clamp(totalWeight, MIN_WEIGHT, MAX_TOTAL_WEIGHT);
tokenBalanceIn = clamp(tokenBalanceIn, BONE, type(uint256).max);

emit Log('tokenAmountOut', tokenAmountOut);

uint256 calc_tokenAmountIn =
bmath.calcSingleInGivenPoolOut(tokenBalanceIn, tokenWeightIn, poolSupply, totalWeight, tokenAmountOut, swapFee);
emit Log('calc_tokenAmountIn', calc_tokenAmountIn);

uint256 calc_poolAmountOut = bmath.calcPoolOutGivenSingleIn(
tokenBalanceIn, tokenWeightIn, poolSupply, totalWeight, calc_tokenAmountIn, swapFee
);
emit Log('calc_poolAmountOut', calc_poolAmountOut);

assert(tokenAmountOut == calc_poolAmountOut);
}

// calcPoolOutGivenSingleIn should be inverse of calcSingleInGivenPoolOut
function testCalcPoolOutGivenSingle_InvCalcSingleInGivenPoolOut(
uint256 tokenBalanceIn,
uint256 tokenWeightIn,
uint256 poolSupply,
uint256 totalWeight,
uint256 tokenAmountIn,
uint256 swapFee
) public {
tokenWeightIn = clamp(tokenWeightIn, MIN_WEIGHT, MAX_WEIGHT);
totalWeight = clamp(totalWeight, MIN_WEIGHT, MAX_TOTAL_WEIGHT);
tokenBalanceIn = clamp(tokenBalanceIn, BONE, type(uint256).max);

emit Log('tokenAmountIn', tokenAmountIn);

uint256 calc_poolAmountOut =
bmath.calcPoolOutGivenSingleIn(tokenBalanceIn, tokenWeightIn, poolSupply, totalWeight, tokenAmountIn, swapFee);
emit Log('calc_poolAmountOut', calc_poolAmountOut);

uint256 calc_tokenAmountIn = bmath.calcSingleInGivenPoolOut(
tokenBalanceIn, tokenWeightIn, poolSupply, totalWeight, calc_poolAmountOut, swapFee
);
emit Log('calc_tokenAmountIn', calc_tokenAmountIn);

assert(tokenAmountIn == calc_tokenAmountIn);
}

// calcPoolOutGivenSingleIn * calcSingleOutGivenPoolIn should be equal to calcOutGivenIn
function testIndirectSwaps_CalcOutGivenIn(
uint256 tokenBalanceIn,
uint256 tokenWeightIn,
uint256 tokenBalanceOut,
uint256 tokenWeightOut,
uint256 tokenAmountIn,
uint256 poolSupply,
uint256 totalWeight,
uint256 swapFee
) public {
tokenWeightIn = clamp(tokenWeightIn, MIN_WEIGHT, MAX_WEIGHT);
tokenWeightOut = clamp(tokenWeightOut, MIN_WEIGHT, MAX_WEIGHT);
totalWeight = clamp(totalWeight, MIN_WEIGHT, MAX_TOTAL_WEIGHT);
tokenBalanceIn = clamp(tokenBalanceIn, BONE, type(uint256).max);
tokenBalanceOut = clamp(tokenBalanceOut, BONE, type(uint256).max);
poolSupply = clamp(poolSupply, BONE, type(uint256).max);
swapFee = clamp(swapFee, MIN_FEE, MAX_FEE);

emit Log('tokenWeightIn', tokenWeightIn);
emit Log('tokenWeightOut', tokenWeightOut);
emit Log('totalWeight', totalWeight);
emit Log('tokenBalanceIn', tokenBalanceIn);
emit Log('tokenBalanceOut', tokenBalanceOut);
emit Log('poolSupply', poolSupply);
emit Log('swapFee', swapFee);

uint256 calc_tokenAmountOut =
bmath.calcOutGivenIn(tokenBalanceIn, tokenWeightIn, tokenBalanceOut, tokenWeightOut, tokenAmountIn, swapFee);
emit Log('calc_tokenAmountOut', calc_tokenAmountOut);

uint256 calc_inv_poolAmountOut =
bmath.calcPoolOutGivenSingleIn(tokenBalanceIn, tokenWeightIn, poolSupply, totalWeight, tokenAmountIn, swapFee);
emit Log('calc_inv_poolAmountOut', calc_inv_poolAmountOut);

uint256 calc_inv_tokenAmountOut = bmath.calcSingleOutGivenPoolIn(
tokenBalanceOut, tokenWeightOut, poolSupply, totalWeight, calc_inv_poolAmountOut, swapFee
);
emit Log('calc_inv_tokenAmountOut', calc_inv_tokenAmountOut);

assert(
calc_tokenAmountOut == calc_inv_tokenAmountOut || calc_tokenAmountOut == calc_inv_tokenAmountOut + 1 // max difference due to rounding errors
|| calc_tokenAmountOut + 1 == calc_inv_tokenAmountOut // max difference due to rounding errors
);
}

// calcPoolInGivenSingleOut * calcSingleInGivenPoolOut should be equal to calcInGivenOut
function testIndirectSwaps_CalcInGivenOut(
uint256 tokenBalanceIn,
uint256 tokenWeightIn,
uint256 tokenBalanceOut,
uint256 tokenWeightOut,
uint256 tokenAmountOut,
uint256 poolSupply,
uint256 totalWeight,
uint256 swapFee
) public {
tokenWeightIn = clamp(tokenWeightIn, MIN_WEIGHT, MAX_WEIGHT);
tokenWeightOut = clamp(tokenWeightOut, MIN_WEIGHT, MAX_WEIGHT);
totalWeight = clamp(totalWeight, MIN_WEIGHT, MAX_TOTAL_WEIGHT);
tokenBalanceIn = clamp(tokenBalanceIn, BONE, type(uint256).max);
tokenBalanceOut = clamp(tokenBalanceOut, BONE, type(uint256).max);
poolSupply = clamp(poolSupply, BONE, type(uint256).max);
swapFee = clamp(swapFee, MIN_FEE, MAX_FEE);

emit Log('tokenWeightIn', tokenWeightIn);
emit Log('tokenWeightOut', tokenWeightOut);
emit Log('totalWeight', totalWeight);
emit Log('tokenBalanceIn', tokenBalanceIn);
emit Log('tokenBalanceOut', tokenBalanceOut);
emit Log('poolSupply', poolSupply);
emit Log('swapFee', swapFee);

uint256 calc_tokenAmountIn =
bmath.calcInGivenOut(tokenBalanceIn, tokenWeightIn, tokenBalanceOut, tokenWeightOut, tokenAmountOut, swapFee);
emit Log('calc_tokenAmountIn', calc_tokenAmountIn);

uint256 calc_inv_tokenAmountIn =
bmath.calcPoolInGivenSingleOut(tokenBalanceOut, tokenWeightOut, poolSupply, totalWeight, tokenAmountOut, swapFee);
emit Log('calc_inv_tokenAmountIn', calc_inv_tokenAmountIn);

uint256 calc_inv_poolAmountIn = bmath.calcSingleInGivenPoolOut(
tokenBalanceIn, tokenWeightIn, poolSupply, totalWeight, calc_inv_tokenAmountIn, swapFee
);
emit Log('calc_inv_poolAmountIn', calc_inv_poolAmountIn);

assert(
calc_tokenAmountIn == calc_inv_poolAmountIn || calc_tokenAmountIn == calc_inv_poolAmountIn + 1 // max difference due to rounding errors
|| calc_tokenAmountIn + 1 == calc_inv_poolAmountIn // max difference due to rounding errors
);
}
}
98 changes: 0 additions & 98 deletions test/invariants/fuzz/BMath.t.sol.invalid

This file was deleted.

0 comments on commit b0744ed

Please sign in to comment.