From d198a380622ae4ec752e919e0d83c534d0c0b36e Mon Sep 17 00:00:00 2001 From: Nelson Taveras <4562733+nvtaveras@users.noreply.github.com> Date: Tue, 5 Nov 2024 16:50:08 +0100 Subject: [PATCH] feat: add cCOP fork tests (#537) --- test/fork/BaseForkTest.sol | 13 +++++++----- test/fork/ForkTests.t.sol | 8 ++++++-- .../GoodDollarExchangeProvider.t.sol | 20 +++++++++---------- 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/test/fork/BaseForkTest.sol b/test/fork/BaseForkTest.sol index 3bda514..51f804a 100644 --- a/test/fork/BaseForkTest.sol +++ b/test/fork/BaseForkTest.sol @@ -9,6 +9,7 @@ import { FixidityLib } from "celo/contracts/common/FixidityLib.sol"; // Interfaces import { IBiPoolManager } from "contracts/interfaces/IBiPoolManager.sol"; import { IBreakerBox } from "contracts/interfaces/IBreakerBox.sol"; +import { IERC20 } from "contracts/interfaces/IERC20.sol"; import { IBroker } from "contracts/interfaces/IBroker.sol"; import { ICeloProxy } from "contracts/interfaces/ICeloProxy.sol"; import { IOwnable } from "contracts/interfaces/IOwnable.sol"; @@ -119,14 +120,16 @@ abstract contract BaseForkTest is Test { function mint(address asset, address to, uint256 amount, bool updateSupply) public { if (asset == lookup("GoldToken")) { - if (!updateSupply) { - revert("BaseForkTest: can't mint GoldToken without updating supply"); - } - vm.prank(address(0)); - IMint(asset).mint(to, amount); + // with L2 Celo, we need to transfer GoldToken to the user manually from the reserve + transferCeloFromReserve(to, amount); return; } deal(asset, to, amount, updateSupply); } + + function transferCeloFromReserve(address to, uint256 amount) internal { + vm.prank(address(mentoReserve)); + IERC20(lookup("GoldToken")).transfer(to, amount); + } } diff --git a/test/fork/ForkTests.t.sol b/test/fork/ForkTests.t.sol index d3ab0b4..c47de51 100644 --- a/test/fork/ForkTests.t.sol +++ b/test/fork/ForkTests.t.sol @@ -45,7 +45,7 @@ import { GoodDollarTradingLimitsForkTest } from "./GoodDollar/TradingLimitsForkT import { GoodDollarSwapForkTest } from "./GoodDollar/SwapForkTest.sol"; import { GoodDollarExpansionForkTest } from "./GoodDollar/ExpansionForkTest.sol"; -contract Alfajores_ChainForkTest is ChainForkTest(ALFAJORES_ID, 1, uints(15)) {} +contract Alfajores_ChainForkTest is ChainForkTest(ALFAJORES_ID, 1, uints(16)) {} contract Alfajores_P0E00_ExchangeForkTest is ExchangeForkTest(ALFAJORES_ID, 0, 0) {} @@ -77,7 +77,9 @@ contract Alfajores_P0E13_ExchangeForkTest is ExchangeForkTest(ALFAJORES_ID, 0, 1 contract Alfajores_P0E14_ExchangeForkTest is ExchangeForkTest(ALFAJORES_ID, 0, 14) {} -contract Celo_ChainForkTest is ChainForkTest(CELO_ID, 1, uints(15)) {} +contract Alfajores_P0E15_ExchangeForkTest is ExchangeForkTest(ALFAJORES_ID, 0, 15) {} + +contract Celo_ChainForkTest is ChainForkTest(CELO_ID, 1, uints(16)) {} contract Celo_P0E00_ExchangeForkTest is ExchangeForkTest(CELO_ID, 0, 0) {} @@ -109,6 +111,8 @@ contract Celo_P0E13_ExchangeForkTest is ExchangeForkTest(CELO_ID, 0, 13) {} contract Celo_P0E14_ExchangeForkTest is ExchangeForkTest(CELO_ID, 0, 14) {} +contract Celo_P0E15_ExchangeForkTest is ExchangeForkTest(CELO_ID, 0, 15) {} + contract Celo_BancorExchangeProviderForkTest is BancorExchangeProviderForkTest(CELO_ID) {} contract Celo_GoodDollarTradingLimitsForkTest is GoodDollarTradingLimitsForkTest(CELO_ID) {} diff --git a/test/unit/goodDollar/GoodDollarExchangeProvider.t.sol b/test/unit/goodDollar/GoodDollarExchangeProvider.t.sol index c87f541..96eb978 100644 --- a/test/unit/goodDollar/GoodDollarExchangeProvider.t.sol +++ b/test/unit/goodDollar/GoodDollarExchangeProvider.t.sol @@ -472,20 +472,20 @@ contract GoodDollarExchangeProviderTest_mintFromExpansion is GoodDollarExchangeP assertApproxEqRel(initialPrice, priceAfter, 1e18 * 0.0001, "Price should remain within 0.01% of initial price"); } - function testFuzz_mintFromExpansion(uint256 reserveRatioScalar) public { + function testFuzz_mintFromExpansion(uint256 _reserveRatioScalar) public { // 0.001% to 100% - reserveRatioScalar = bound(reserveRatioScalar, 1e18 * 0.00001, 1e18); + _reserveRatioScalar = bound(_reserveRatioScalar, 1e18 * 0.00001, 1e18); uint256 initialTokenSupply = poolExchange.tokenSupply; uint32 initialReserveRatio = poolExchange.reserveRatio; uint256 priceBefore = exchangeProvider.currentPrice(exchangeId); - uint256 expectedReserveRatio = (uint256(initialReserveRatio) * reserveRatioScalar) / 1e18; + uint256 expectedReserveRatio = (uint256(initialReserveRatio) * _reserveRatioScalar) / 1e18; vm.expectEmit(true, true, true, true); emit ReserveRatioUpdated(exchangeId, uint32(expectedReserveRatio)); vm.prank(expansionControllerAddress); - uint256 amountToMint = exchangeProvider.mintFromExpansion(exchangeId, reserveRatioScalar); + uint256 amountToMint = exchangeProvider.mintFromExpansion(exchangeId, _reserveRatioScalar); IBancorExchangeProvider.PoolExchange memory poolExchangeAfter = exchangeProvider.getPoolExchange(exchangeId); uint256 priceAfter = exchangeProvider.currentPrice(exchangeId); @@ -720,7 +720,7 @@ contract GoodDollarExchangeProviderTest_updateRatioForReward is GoodDollarExchan } function test_updateRatioForReward_whenRewardIsSmall_shouldReturnCorrectRatioAndEmit() public { - uint256 reward = 1e18; // 1 token + uint256 _reward = 1e18; // 1 token // formula: newRatio = reserveBalance / ((tokenSupply + reward) * currentPrice) // reserveRatio = 200_000 / ((7_000_000_000 + 1) * 0.000100000002) ≈ 0.2857142799 uint32 expectedReserveRatio = 28571427; @@ -729,7 +729,7 @@ contract GoodDollarExchangeProviderTest_updateRatioForReward is GoodDollarExchan vm.expectEmit(true, true, true, true); emit ReserveRatioUpdated(exchangeId, expectedReserveRatio); vm.prank(expansionControllerAddress); - exchangeProvider.updateRatioForReward(exchangeId, reward); + exchangeProvider.updateRatioForReward(exchangeId, _reward); IBancorExchangeProvider.PoolExchange memory poolExchangeAfter = exchangeProvider.getPoolExchange(exchangeId); uint256 priceAfter = exchangeProvider.currentPrice(exchangeId); @@ -737,14 +737,14 @@ contract GoodDollarExchangeProviderTest_updateRatioForReward is GoodDollarExchan assertEq(poolExchangeAfter.reserveRatio, expectedReserveRatio, "Reserve ratio should be updated correctly"); assertEq( poolExchangeAfter.tokenSupply, - poolExchange.tokenSupply + reward, + poolExchange.tokenSupply + _reward, "Token supply should increase by reward amount" ); assertApproxEqRel(priceBefore, priceAfter, 1e18 * 0.0001, "Price should remain within 0.01% of initial price"); } function test_updateRatioForReward_whenRewardIsLarge_shouldReturnCorrectRatioAndEmit() public { - uint256 reward = 1_000_000_000 * 1e18; // 1 billion tokens + uint256 _reward = 1_000_000_000 * 1e18; // 1 billion tokens // formula: newRatio = reserveBalance / ((tokenSupply + reward) * currentPrice) // reserveRatio = 200_000 / ((7_000_000_000 + 1_000_000_000) * 0.000100000002) ≈ 0.2499999950000... @@ -754,7 +754,7 @@ contract GoodDollarExchangeProviderTest_updateRatioForReward is GoodDollarExchan vm.expectEmit(true, true, true, true); emit ReserveRatioUpdated(exchangeId, expectedReserveRatio); vm.prank(expansionControllerAddress); - exchangeProvider.updateRatioForReward(exchangeId, reward); + exchangeProvider.updateRatioForReward(exchangeId, _reward); IBancorExchangeProvider.PoolExchange memory poolExchangeAfter = exchangeProvider.getPoolExchange(exchangeId); uint256 priceAfter = exchangeProvider.currentPrice(exchangeId); @@ -762,7 +762,7 @@ contract GoodDollarExchangeProviderTest_updateRatioForReward is GoodDollarExchan assertEq(poolExchangeAfter.reserveRatio, expectedReserveRatio, "Reserve ratio should be updated correctly"); assertEq( poolExchangeAfter.tokenSupply, - poolExchange.tokenSupply + reward, + poolExchange.tokenSupply + _reward, "Token supply should increase by reward amount" ); assertApproxEqRel(priceBefore, priceAfter, 1e18 * 0.0001, "Price should remain within 0.01% of initial price");