Skip to content

Instantly share code, notes, and snippets.

@beirao
Last active September 5, 2023 07:53
Show Gist options
  • Save beirao/258ccfa9b07367b1c614329bbf54e41a to your computer and use it in GitHub Desktop.
Save beirao/258ccfa9b07367b1c614329bbf54e41a to your computer and use it in GitHub Desktop.
Farkid review POCs
// 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