Files
tycho-protocol-sdk/evm/test/FraxV3SFraxAdapter.t.sol
Domenico e484ea28ca Sdk implementation: Sfrax adapter and substream (#91)
* feat: initial setup

* feat: implemented getCapabilities and getTokens

* chore: adjusted getPoolIds

* feat: Initial implementation of getLimits()

* feat: implemented getLimits, getTokens and internal functions for amounts

* feat: implemented price

* feat: implemented swap function

* fix and test: fixed minor issues on adapter and setup test

* debugging price function

* fix: debugged price function and fixed getPriceAt function

* test: testOneIncreasingPriceFoundFraxV3SFrax

* fix: debugging and fixing buy function

* fix: fixed getPriceAt

* test: testing post trade price

* fix: Fixed getPriceAt

* fix: Fixed getLimits

* fix: Fixed prices and improved readability

* fix: Fixed price and transfers in swap

* feat: Finished tests

* chore: Changed approve to safeIncreaseAllowance

* feat: created substream for staked frax

* feat: remove useless files

* feat: fixed dependencies in cargo.toml

* feat: rename folder

* feat: updated cargo.lock

* feat: changed lib.rs, added modules.rs

* feat: update modules.rs with corrects addresses

* feat: rename folder in ethereum-sfrax

* feat: remove useless comments, change locked asset address, rename

* feat: undo changes on mod.rs in ethereum-balancer

* feat: rename variable

* feat: update substreams/cargo.toml

* feat: modify ristfmt.toml

* feat: performed code formatting

* feat: modify src/abi

* feat: performed formatting with nightly

* feat: fix addition opeation

* feat: adjust code with for i, f

* feat: performed fmt inside ethereum-sfrax folder

* feat: performed clippy

* feat: fix with clippy warning suggests

* feat: undo any change in ethereum-balancer

* feat: change stakedfrax_contract.rs

* fix: stakedfrax_contract.rs

* feat: add blank line

* feat: add #[allow(clippy::all)] on ethereum-sfrax/src/abi/mod.rs

* feat: update comments on pool_factories.rs

* feat: update cargo.toml and substreams.yaml

* feat: add tycho evm in pb folder

* feat: add params to take contracts' addresses

* feat: add logic to map rewards_cycle

* feat: performed fmt and fix versioning

* feat: remove useless functions

* feat: add logic to track rewards_to_distribute

* feat: passing CI

* fix: substreams.yaml

* feat: fixed params in manifest

Co-authored-by: mrBovo <bovo.ignazio@proton.me>

* feat: fixed error in map_relative_balances function

* feat: passing CI checks

* fix: 🐛 hex-binary address encoding + refactoring vault-> underlying map

* style: 💄 fix formatting

* feat: Implemented testPoolBehaviour

* alignment with propeller main

* Update forge-std submodule reference to include ds-test

* files update to match propeller/main

* creating integration_test fir sfrax

* fixed FraxV3SFraxAdapter.sol import paths

* updated with correct addresses FraxV3SFraxAdapter manifest.yaml

* updated sfrax manifest.yaml

* updated to support sdk

* integration_test sfrax updated

* fix: 🐛 add reward processing

* chore: ♻️ minor cleanups

* fix: Fixed adapter limits

* fix: fix adapter and substream sdk tests

* fix: Fixed CI errors

* chore: fmt

* chore: Removed unused line

* fix: Fixed clippy warnings

* chore: formatted with rustup

* chore: Removed unused line

* chore: post-build formatting

* chore: Formatting using different toolchain vesion

* chore: 💄 format

* chore: 💄 format 2

* chore: Using static address for frax

* feat: Added second constructor param for sfrax

* fix: Fixed limits on frax sell

* chore: Fixed merge conflict with sfraxeth

* chore: Remove sfraxeth_contract changes

* chore: Fixed EOFs

* fix: Fixed fmt on stakedfrax contract

---------

Co-authored-by: mp-web3 <mp.web3.t@gmail.com>
Co-authored-by: gabrir99 <gabri.ruini@gmail.com>
Co-authored-by: mrBovo <bovo.ignazio@proton.me>
Co-authored-by: Ignazio Bovo <ignazio@jsgenesis.com>
Co-authored-by: mrBovo <bovoignazio.dev@gmail.com>
Co-authored-by: Mattia <mp.web3@gmail.com>
2024-10-25 18:53:06 +01:00

247 lines
8.4 KiB
Solidity

// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.13;
import "./AdapterTest.sol";
import "forge-std/Test.sol";
import "src/interfaces/ISwapAdapterTypes.sol";
import "src/libraries/FractionMath.sol";
import "src/libraries/FractionMath.sol";
import "src/sfrax/FraxV3SFraxAdapter.sol";
/// @title TemplateSwapAdapterTest
/// @dev This is a template for a swap adapter test.
/// Test all functions that are implemented in your swap adapter, the two test
/// included here are just an example.
/// Feel free to use UniswapV2SwapAdapterTest and BalancerV2SwapAdapterTest as a
/// reference.
contract FraxV3SFraxAdapterTest is Test, ISwapAdapterTypes, AdapterTest {
using FractionMath for Fraction;
FraxV3SFraxAdapter adapter;
ISFrax constant SFRAX = ISFrax(0xA663B02CF0a4b149d2aD41910CB81e23e1c41c32);
IERC20 constant FRAX = IERC20(0x853d955aCEf822Db058eb8505911ED77F175b99e);
address constant FRAX_ADDRESS = address(FRAX);
address constant SFRAX_ADDRESS = address(SFRAX);
uint256 constant TEST_ITERATIONS = 100;
uint256 constant AMOUNT0 = 1000000000000000000;
function setUp() public {
uint256 forkBlock = 19270612;
vm.createSelectFork(vm.rpcUrl("mainnet"), forkBlock);
adapter = new FraxV3SFraxAdapter(SFRAX_ADDRESS, FRAX_ADDRESS);
vm.label(address(FRAX), "FRAX");
vm.label(address(SFRAX), "SFRAX");
}
/// @dev set lower limit to greater than 1, because previewDeposit returns 0
/// with an amountIn == 1
function testPriceFuzzFraxV3SFrax(uint256 amount0, uint256 amount1)
public
{
uint256[] memory limits =
adapter.getLimits(bytes32(0), FRAX_ADDRESS, SFRAX_ADDRESS);
vm.assume(amount0 < limits[0]);
vm.assume(amount0 > 1);
vm.assume(amount1 < limits[0]);
vm.assume(amount1 > 1);
uint256[] memory amounts = new uint256[](2);
amounts[0] = amount0;
amounts[1] = amount1;
Fraction[] memory prices =
adapter.price(bytes32(0), FRAX_ADDRESS, SFRAX_ADDRESS, amounts);
for (uint256 i = 0; i < prices.length; i++) {
assertGt(prices[i].numerator, 0);
assertGt(prices[i].denominator, 0);
}
}
function testSwapFuzzFraxV3WithFrax(uint256 specifiedAmount, bool isBuy)
public
{
OrderSide side = isBuy ? OrderSide.Buy : OrderSide.Sell;
bytes32 pair = bytes32(0);
uint256[] memory limits =
adapter.getLimits(pair, FRAX_ADDRESS, SFRAX_ADDRESS);
if (side == OrderSide.Buy) {
vm.assume(specifiedAmount < limits[1]);
deal(address(FRAX), address(this), type(uint256).max);
FRAX.approve(address(adapter), type(uint256).max);
} else {
vm.assume(specifiedAmount < limits[0]);
deal(address(FRAX), address(this), specifiedAmount);
FRAX.approve(address(adapter), specifiedAmount);
}
uint256 frax_balance = FRAX.balanceOf(address(this));
uint256 sfrax_balance = IERC20(SFRAX_ADDRESS).balanceOf(address(this));
ISFrax(SFRAX_ADDRESS).totalAssets();
Trade memory trade = adapter.swap(
pair, FRAX_ADDRESS, SFRAX_ADDRESS, side, specifiedAmount
);
if (trade.calculatedAmount > 0) {
if (side == OrderSide.Buy) {
assertEq(
specifiedAmount,
IERC20(SFRAX_ADDRESS).balanceOf(address(this))
- sfrax_balance
);
assertEq(
trade.calculatedAmount,
frax_balance - FRAX.balanceOf(address(this))
);
} else {
assertEq(
specifiedAmount,
frax_balance - FRAX.balanceOf(address(this))
);
assertEq(
trade.calculatedAmount,
IERC20(SFRAX_ADDRESS).balanceOf(address(this))
- sfrax_balance
);
}
}
}
function testSwapFuzzFraxV3WithSFrax(uint256 specifiedAmount, bool isBuy)
public
{
OrderSide side = isBuy ? OrderSide.Buy : OrderSide.Sell;
bytes32 pair = bytes32(0);
uint256[] memory limits =
adapter.getLimits(pair, SFRAX_ADDRESS, FRAX_ADDRESS);
if (side == OrderSide.Buy) {
vm.assume(specifiedAmount < limits[1]);
deal(SFRAX_ADDRESS, address(this), type(uint256).max);
IERC20(SFRAX_ADDRESS).approve(address(adapter), type(uint256).max);
} else {
vm.assume(specifiedAmount < limits[0]);
deal(address(SFRAX_ADDRESS), address(this), specifiedAmount);
IERC20(SFRAX_ADDRESS).approve(address(adapter), specifiedAmount);
}
uint256 sfrax_balance = IERC20(SFRAX_ADDRESS).balanceOf(address(this));
uint256 frax_balance = FRAX.balanceOf(address(this));
Trade memory trade = adapter.swap(
pair, SFRAX_ADDRESS, FRAX_ADDRESS, side, specifiedAmount
);
if (trade.calculatedAmount > 0) {
if (side == OrderSide.Buy) {
assertEq(
specifiedAmount,
FRAX.balanceOf(address(this)) - frax_balance
);
assertEq(
trade.calculatedAmount,
sfrax_balance
- IERC20(SFRAX_ADDRESS).balanceOf(address(this))
);
} else {
assertEq(
specifiedAmount,
sfrax_balance
- IERC20(SFRAX_ADDRESS).balanceOf(address(this))
);
assertEq(
trade.calculatedAmount,
FRAX.balanceOf(address(this)) - frax_balance
);
}
}
}
function testSwapSellIncreasingFraxV3() public {
executeIncreasingSwapsFraxV3(OrderSide.Sell, true);
executeIncreasingSwapsFraxV3(OrderSide.Sell, false);
}
function testSwapBuyIncreasingFraxV3() public {
executeIncreasingSwapsFraxV3(OrderSide.Buy, true);
executeIncreasingSwapsFraxV3(OrderSide.Buy, false);
}
function executeIncreasingSwapsFraxV3(OrderSide side, bool isFrax)
internal
{
bytes32 pair = bytes32(0);
uint256[] memory amounts = new uint256[](TEST_ITERATIONS);
for (uint256 i = 0; i < TEST_ITERATIONS; i++) {
amounts[i] = 1000 * (i + 1) * 10 ** 18;
}
Trade[] memory trades = new Trade[](TEST_ITERATIONS);
uint256 beforeSwap;
for (uint256 i = 0; i < TEST_ITERATIONS; i++) {
beforeSwap = vm.snapshot();
if (isFrax) {
deal(FRAX_ADDRESS, address(this), type(uint256).max);
FRAX.approve(address(adapter), type(uint256).max);
trades[i] = adapter.swap(
pair, FRAX_ADDRESS, SFRAX_ADDRESS, side, amounts[i]
);
} else {
deal(SFRAX_ADDRESS, address(this), amounts[i]);
IERC20(SFRAX_ADDRESS).approve(address(adapter), amounts[i]);
trades[i] = adapter.swap(
pair, SFRAX_ADDRESS, FRAX_ADDRESS, side, amounts[i]
);
}
vm.revertTo(beforeSwap);
}
for (uint256 i = 1; i < TEST_ITERATIONS - 1; i++) {
assertLe(trades[i].calculatedAmount, trades[i + 1].calculatedAmount);
assertLe(trades[i].gasUsed, trades[i + 1].gasUsed);
}
}
function testGetLimitsFraxV3() public {
uint256[] memory limits =
adapter.getLimits(bytes32(0), FRAX_ADDRESS, SFRAX_ADDRESS);
assertEq(limits.length, 2);
}
function testGetTokensFraxV3() public {
address[] memory tokens = adapter.getTokens(bytes32(0));
assertEq(tokens[0], FRAX_ADDRESS);
assertEq(tokens[1], SFRAX_ADDRESS);
}
function testGetCapabilitiesFraxV3SFrax() public {
Capability[] memory res =
adapter.getCapabilities(bytes32(0), FRAX_ADDRESS, SFRAX_ADDRESS);
assertEq(res.length, 5);
}
// This test is currently broken due to a bug in runPoolBehaviour
// with constant price pools.
// function testPoolBehaviourFraxV3Sfrax() public {
// bytes32[] memory poolIds = new bytes32[](1);
// poolIds[0] = bytes32(0);
// runPoolBehaviourTest(adapter, poolIds);
// }
}