-
-
Save beirao/258ccfa9b07367b1c614329bbf54e41a to your computer and use it in GitHub Desktop.
Farkid review POCs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
pragma solidity ^0.8.0; | |
import "forge-std/console.sol"; | |
import {EncoderLib} from "src/encoder/EncoderLib.sol"; | |
import {MonoPool} from "src/MonoPool.sol"; | |
import {MockERC20} from "test/mock/MockERC20.sol"; | |
import {BaseMonoPoolTest} from "./BaseMonoPoolTest.sol"; | |
import {SafeTransferLib} from "lib/solady/src/utils/SafeTransferLib.sol"; | |
/// @dev Generic contract to test swap with native token on the mono pool | |
/// @author KONFeature <https://github.com/KONFeature> | |
contract BeiraoReviewTest is BaseMonoPoolTest { | |
using EncoderLib for bytes; | |
using SafeTransferLib for address; | |
/// @dev The pool we will test | |
MonoPool private pool; | |
address internal liquidityProvider2; | |
function setUp() public { | |
_initBaseMonoPoolTest(); | |
liquidityProvider2 = _newUser("liquidityProvider2"); | |
// Build our pool | |
pool = new MonoPool( | |
address(token0), | |
address(0), | |
0, | |
feeReceiver, | |
protocolFee | |
); | |
//_disableProtocolFees(pool); | |
} | |
/* -------------------------------------------------------------------------- */ | |
/* Simple swap test's */ | |
/* -------------------------------------------------------------------------- */ | |
function test_H2() public withNativeLiquidity(1 ether, 1 ether) { | |
addNativeLiquidity(5 ether, 5 ether, swapUser); | |
_logPoolState(pool); | |
// send 1 wei of token0 | |
token0.mint(swapUser, 1); | |
vm.prank(swapUser); | |
token0.transfer(address(pool), 1); | |
// Prank the eth to the user directly | |
token0.mint(swapUser, 6 ether + 1); | |
vm.prank(swapUser); | |
token0.approve(address(pool), 6 ether + 1); | |
// Build the send => swap => removeLiq op | |
bytes memory program = EncoderLib | |
.init() | |
.appendSend(true, swapUser, 6 ether + 1) | |
.appendSwap(false, 3 ether).appendRemoveLiquidity(3 ether).done(); // you need to choose this amount carefully to be able to remove liquidity | |
// Send it | |
vm.prank(swapUser); | |
pool.execute(program); | |
_logPoolState(pool); | |
} | |
//! This test does revert but shouldn't | |
function test_swap0to1_forceSend_H1() | |
public | |
withNativeLiquidity(100 ether, 100 ether) | |
{ | |
send1WeiOfToken0andNative(); | |
_logPoolState(pool); | |
_swap0to1Native(1 ether); | |
_logPoolState(pool); | |
} | |
//! This does revert but shouldn't | |
function test_swap1to0_forceSend_H1() | |
public | |
withNativeLiquidity(100 ether, 100 ether) | |
{ | |
send1WeiOfToken0andNative(); | |
_logPoolState(pool); | |
_swap1to0Native(1 ether); | |
_logPoolState(pool); | |
} | |
//! This does revert but shouldn't | |
function test_addLiquidity_forceSend_H1() | |
public | |
withNativeLiquidity(100 ether, 100 ether) | |
{ | |
send1WeiOfToken0andNative(); | |
_logPoolState(pool); | |
addNativeLiquidity(100 ether, 100 ether, liquidityProvider); | |
_logPoolState(pool); | |
} | |
//! This does revert but shouldn't | |
function test_removeHalfLiquidityThenTryToSwap0to1_forceSend_H1() | |
public | |
withNativeLiquidity(100 ether, 100 ether) | |
{ | |
send1WeiOfToken0andNative(); | |
_logPoolState(pool); | |
removeHalfNativeLiquidity(); | |
_logPoolState(pool); | |
_swap0to1Native(1 ether); | |
_logPoolState(pool); | |
} | |
//! This does revert but shouldn't | |
function test_removeHalfLiquidityThenTryToSwap1to0_forceSend_H1() | |
public | |
withNativeLiquidity(100 ether, 100 ether) | |
{ | |
send1WeiOfToken0andNative(); | |
_logPoolState(pool); | |
removeHalfNativeLiquidity(); | |
_logPoolState(pool); | |
_swap1to0Native(1 ether); | |
_logPoolState(pool); | |
} | |
//! This does revert but shouldn't | |
function test_removeAllLiquidityThenAddLiquidityThenTryToSwap0to1_forceSend_H1() | |
public | |
withNativeLiquidity(100 ether, 100 ether) | |
{ | |
send1WeiOfToken0andNative(); | |
_logPoolState(pool); | |
removeNativeLiquidity(); | |
_logPoolState(pool); | |
addNativeLiquidity(100 ether, 100 ether, liquidityProvider); | |
_logPoolState(pool); | |
_swap0to1Native(1 ether); | |
_logPoolState(pool); | |
} | |
//! This does revert but shouldn't | |
function test_removeAllLiquidityThenAddLiquidityThenTryToSwap1to0_forceSend_H1() | |
public | |
withNativeLiquidity(100 ether, 100 ether) | |
{ | |
send1WeiOfToken0andNative(); | |
_logPoolState(pool); | |
removeNativeLiquidity(); | |
_logPoolState(pool); | |
addNativeLiquidity(100 ether, 100 ether, liquidityProvider); | |
_logPoolState(pool); | |
_swap1to0Native(1 ether); | |
_logPoolState(pool); | |
} | |
//! This does not revert but should | |
function testFail_unlockH1WithM1_forceSend_M1() | |
public | |
withNativeLiquidity(100 ether, 100 ether) | |
{ | |
send1WeiOfToken0andNative(); | |
_logPoolState(pool); | |
uint swapAmount = 1 ether; | |
// Mint token & approve transfer | |
vm.deal(swapUser, swapAmount); | |
// Build the swap op | |
// forgefmt: disable-next-item | |
bytes memory program = EncoderLib | |
.init() | |
.appendSwap(false, swapAmount) | |
.appendReceive(false, swapAmount) | |
.appendSendAll(true, swapUser) | |
.done(); | |
// Send it | |
vm.prank(swapUser); | |
pool.execute{value: swapAmount - 1}(program); | |
_logPoolState(pool); | |
} | |
function testFail_msgsenderDiffAmounts_M1() | |
public | |
withNativeLiquidity(100 ether, 100 ether) | |
{ | |
uint256 swapAmount = 1 ether; | |
vm.deal(address(this), 1 ether); | |
address(pool).forceSafeTransferETH(1, 0); | |
// Mint token & approve transfer | |
vm.deal(swapUser, swapAmount); | |
// Build the swap op | |
// forgefmt: disable-next-item | |
bytes memory program = EncoderLib | |
.init() | |
.appendSwap(false, swapAmount) | |
.appendReceive(false, swapAmount) | |
.appendSendAll(true, swapUser) | |
.done(); | |
// Send it | |
// TODO: SHOULDN'T BE OK | |
vm.prank(swapUser); | |
pool.execute{value: swapAmount - 1}(program); | |
} | |
/* -------------------------------------------------------------------------- */ | |
/* Helper's to swap native tokens */ | |
/* -------------------------------------------------------------------------- */ | |
function _swap0to1Native(uint256 swapAmount) internal { | |
// Prank the eth to the user directly | |
token0.mint(swapUser, swapAmount); | |
vm.prank(swapUser); | |
token0.approve(address(pool), swapAmount); | |
// Build the swap op | |
// forgefmt: disable-next-item | |
bytes memory program = EncoderLib | |
.init() | |
.appendSwap(true, swapAmount) | |
.appendReceive(true, swapAmount) | |
.appendSendAll(false, swapUser) | |
.done(); | |
// Send it | |
vm.prank(swapUser); | |
pool.execute(program); | |
} | |
function _swap1to0Native(uint256 swapAmount) internal { | |
// Mint token & approve transfer | |
vm.deal(swapUser, swapAmount); | |
// Build the swap op | |
// forgefmt: disable-next-item | |
bytes memory program = EncoderLib | |
.init() | |
.appendSwap(false, swapAmount) | |
.appendReceive(false, swapAmount) | |
.appendSendAll(true, swapUser) | |
.done(); | |
// Send it | |
vm.prank(swapUser); | |
pool.execute{value: swapAmount}(program); | |
} | |
modifier withNativeLiquidity(uint256 amount0, uint256 amount1) { | |
// Mint some initial tokens to the liquidity provider | |
addNativeLiquidity(amount0, amount1, liquidityProvider); | |
_; | |
} | |
function addNativeLiquidity( | |
uint256 amount0, | |
uint256 amount1, | |
address prankedUser | |
) public { | |
token0.mint(prankedUser, amount0); | |
vm.deal(prankedUser, amount1); | |
// Authorise the pool to spend our tokens | |
vm.startPrank(prankedUser); | |
token0.approve(address(pool), amount1); | |
vm.stopPrank(); | |
// Build the program to execute | |
// forgefmt: disable-next-item | |
bytes memory program = EncoderLib | |
.init() | |
.appendAddLiquidity(amount0, amount1) | |
.appendReceiveAll(true) | |
.appendReceiveAll(false) | |
.done(); | |
// Execute it | |
vm.prank(prankedUser); | |
pool.execute{value: amount1}(program); | |
} | |
function removeNativeLiquidity() public { | |
uint256 prevPosition = pool.getPosition(liquidityProvider); | |
bytes memory program = EncoderLib | |
.init() | |
.appendRemoveLiquidity(prevPosition) | |
.appendSendAll(true, liquidityProvider) | |
.appendSendAll(false, liquidityProvider) | |
.done(); | |
// Execute it | |
vm.prank(liquidityProvider); | |
pool.execute(program); | |
} | |
function removeHalfNativeLiquidity() public { | |
uint256 prevPosition = pool.getPosition(liquidityProvider); | |
bytes memory program = EncoderLib | |
.init() | |
.appendRemoveLiquidity(prevPosition / 2) | |
.appendSendAll(true, liquidityProvider) | |
.appendSendAll(false, liquidityProvider) | |
.done(); | |
// Execute it | |
vm.prank(liquidityProvider); | |
pool.execute(program); | |
} | |
function send1WeiOfToken0andNative() public { | |
// send 1 wei of ETH | |
vm.deal(address(this), 1); | |
address(pool).forceSafeTransferETH(1, 0); | |
// send 1 wei of token0 | |
token0.mint(swapUser, 1); | |
vm.prank(swapUser); | |
token0.transfer(address(pool), 1); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment