Skip to content

Commit

Permalink
Take portion tests (#377)
Browse files Browse the repository at this point in the history
* take portion test

* take portion test native

* correct comment

* take portion on input test

* remove console logs oops
  • Loading branch information
hensha256 authored Aug 21, 2024
1 parent 5486943 commit 1180951
Showing 1 changed file with 129 additions and 1 deletion.
130 changes: 129 additions & 1 deletion test/integration-tests/UniswapV4.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,16 @@ import { expect } from './shared/expect'
import { IPermit2, PoolManager, PositionManager, UniversalRouter } from '../../typechain'
import { abi as TOKEN_ABI } from '../../artifacts/solmate/src/tokens/ERC20.sol/ERC20.json'
import { resetFork, WETH, DAI, USDC, PERMIT2 } from './shared/mainnetForkHelpers'
import { ALICE_ADDRESS, DEADLINE, ETH_ADDRESS, MAX_UINT, MAX_UINT160, MSG_SENDER } from './shared/constants'
import {
ALICE_ADDRESS,
DEADLINE,
ETH_ADDRESS,
MAX_UINT,
MAX_UINT160,
MSG_SENDER,
ONE_PERCENT_BIPS,
OPEN_DELTA,
} from './shared/constants'
import { expandTo18DecimalsBN, expandTo6DecimalsBN } from './shared/helpers'
import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'
import deployUniversalRouter from './shared/deployUniversalRouter'
Expand Down Expand Up @@ -201,6 +210,125 @@ describe('Uniswap V4 Tests:', () => {
expect(daiBalanceBefore.sub(daiBalanceAfter)).to.be.eq(amountInDAI)
})

it('completes a v4 exactIn 2 hop swap, with take portion on output', async () => {
// DAI -> USDC -> WETH
let currencyIn = daiContract.address
v4Planner.addAction(Actions.SWAP_EXACT_IN, [
{
currencyIn,
path: encodeMultihopExactInPath([DAI_USDC.poolKey, USDC_WETH.poolKey], currencyIn),
amountIn: amountInDAI,
amountOutMinimum: minAmountOutNative,
},
])
// take 1% of the output to alice, then settle and take the rest to the caller
v4Planner.addAction(Actions.TAKE_PORTION, [WETH.address, alice.address, ONE_PERCENT_BIPS])
v4Planner.addAction(Actions.SETTLE_TAKE_PAIR, [currencyIn, wethContract.address])

planner.addCommand(CommandType.V4_SWAP, [v4Planner.actions, v4Planner.params])

const wethBalanceBeforeAlice = await wethContract.balanceOf(alice.address)

const { wethBalanceBefore, wethBalanceAfter } = await executeRouter(
planner,
bob,
router,
wethContract,
daiContract,
usdcContract
)

const wethBalanceAfterAlice = await wethContract.balanceOf(alice.address)

const aliceFee = wethBalanceAfterAlice.sub(wethBalanceBeforeAlice)
const bobEarnings = wethBalanceAfter.sub(wethBalanceBefore)
const totalOut = aliceFee.add(bobEarnings)

expect(totalOut).to.be.gte(minAmountOutNative)
expect(totalOut.mul(ONE_PERCENT_BIPS).div(10_000)).to.eq(aliceFee)
})

it('completes a v4 exactIn 2 hop swap, with take portion on input', async () => {
// DAI -> USDC -> WETH
let currencyIn = daiContract.address
// trade is 1% less than previously, so adjust expected output
let minOut = minAmountOutNative.mul(99).div(100)

// settle the input tokens to the pool manager
v4Planner.addAction(Actions.SETTLE, [currencyIn, amountInDAI, true])
// take 1% of the input tokens
v4Planner.addAction(Actions.TAKE_PORTION, [currencyIn, alice.address, ONE_PERCENT_BIPS])
// swap using the OPEN_DELTA as input amount
v4Planner.addAction(Actions.SWAP_EXACT_IN, [
{
currencyIn,
path: encodeMultihopExactInPath([DAI_USDC.poolKey, USDC_WETH.poolKey], currencyIn),
amountIn: OPEN_DELTA,
amountOutMinimum: minOut,
},
])
// take the output weth
v4Planner.addAction(Actions.TAKE_ALL, [wethContract.address, minOut])

planner.addCommand(CommandType.V4_SWAP, [v4Planner.actions, v4Planner.params])

const daiBalanceBeforeAlice = await daiContract.balanceOf(alice.address)

const { daiBalanceBefore, daiBalanceAfter } = await executeRouter(
planner,
bob,
router,
wethContract,
daiContract,
usdcContract
)

const daiBalanceAfterAlice = await daiContract.balanceOf(alice.address)

const aliceFee = daiBalanceAfterAlice.sub(daiBalanceBeforeAlice)
const bobSpent = daiBalanceBefore.sub(daiBalanceAfter)

expect(bobSpent.mul(ONE_PERCENT_BIPS).div(10_000)).to.eq(aliceFee)
})

it('completes a v4 exactIn 2 hop swap, with take portion native', async () => {
// DAI -> USDC -> ETH
let currencyIn = daiContract.address
v4Planner.addAction(Actions.SWAP_EXACT_IN, [
{
currencyIn,
path: encodeMultihopExactInPath([DAI_USDC.poolKey, ETH_USDC.poolKey], currencyIn),
amountIn: amountInDAI,
amountOutMinimum: minAmountOutNative,
},
])
// take 1% of the output to alice, then settle and take the rest to the caller
v4Planner.addAction(Actions.TAKE_PORTION, [ETH_ADDRESS, alice.address, ONE_PERCENT_BIPS])
v4Planner.addAction(Actions.SETTLE_TAKE_PAIR, [currencyIn, ETH_ADDRESS])

planner.addCommand(CommandType.V4_SWAP, [v4Planner.actions, v4Planner.params])

const ethBalanceBeforeAlice: BigNumber = await ethers.provider.getBalance(alice.address)

const { ethBalanceBefore, ethBalanceAfter, gasSpent } = await executeRouter(
planner,
bob,
router,
wethContract,
daiContract,
usdcContract
)

const ethBalanceAfterAlice: BigNumber = await ethers.provider.getBalance(alice.address)

const aliceFee = ethBalanceAfterAlice.sub(ethBalanceBeforeAlice)
const bobEarnings = ethBalanceAfter.add(gasSpent).sub(ethBalanceBefore)
const totalOut = aliceFee.add(bobEarnings)

expect(totalOut).to.be.gte(minAmountOutNative)
expect(totalOut.mul(ONE_PERCENT_BIPS).div(10_000)).to.eq(aliceFee)
})

it('completes a v4 exactOutSingle swap', async () => {
v4Planner.addAction(Actions.SWAP_EXACT_OUT_SINGLE, [
{
Expand Down

0 comments on commit 1180951

Please sign in to comment.